{
  "openapi": "3.1.0",
  "info": {
    "title": "RegistryRadar Developer API",
    "version": "1",
    "summary": "Public sex offender registry records from the US registries RegistryRadar ingests, plus researched datasets on registry law worldwide.",
    "description": "A read-only JSON API. Every response is filtered by the declared purpose recorded against the calling key, because several US jurisdictions limit by statute what their registry data may be used for. `withheld` on a record search says how many records were removed and why — a non-zero `withheld` means we hold records there that your purpose may not receive, and does NOT mean the area is clear. `covered` separately says whether we mirror any registry covering that point at all. An empty result with `covered: false` means we cannot see there; it is never an all-clear.",
    "termsOfService": "https://registryradar.app/terms",
    "contact": {
      "name": "Broctic",
      "email": "support@broctic.com",
      "url": "https://registryradar.app/api"
    },
    "license": {
      "name": "RegistryRadar API terms of service",
      "url": "https://registryradar.app/terms"
    }
  },
  "servers": [
    {
      "url": "https://api.registryradar.app",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "records",
      "description": "Registry records for a place."
    },
    {
      "name": "atlas",
      "description": "Researched registry law, per country and per US jurisdiction."
    },
    {
      "name": "policy",
      "description": "What your key may be used for, jurisdiction by jurisdiction."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer rr_live_… Keys are prefixed rr_live_ for production and rr_test_ for test. Never send a key in a query string: the API rejects that with a 400 and you should treat the key as exposed."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Equivalent to the bearer form. Accepted for clients that make headers awkward."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Stable snake_case identifier. Safe to switch on; never reworded once published.",
            "examples": [
              "missing_api_key",
              "invalid_api_key",
              "key_in_query_string",
              "insufficient_scope",
              "ip_not_allowed",
              "origin_not_allowed",
              "quota_exceeded",
              "invalid_request",
              "not_found"
            ]
          },
          "message": {
            "type": "string",
            "description": "One sentence for a human reading a log."
          },
          "docs": {
            "type": "string",
            "description": "Deep link, set where the fix is not obvious."
          }
        }
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "paths": {
    "/v1/api/records/search": {
      "get": {
        "tags": [
          "records"
        ],
        "summary": "Registrants near a point",
        "description": "Radius search around a coordinate. Results are filtered by the key's declared purpose. Read `withheld`, `withheldReasons` and `covered` before rendering anything: a short list can mean we filtered, and an empty list can mean we hold no source for that area.",
        "parameters": [
          {
            "name": "latitude",
            "in": "query",
            "required": true,
            "description": "−90 to 90.",
            "schema": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            }
          },
          {
            "name": "longitude",
            "in": "query",
            "required": true,
            "description": "−180 to 180.",
            "schema": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          {
            "name": "radiusMeters",
            "in": "query",
            "description": "100 to 80467 (50 miles). Default 1609.",
            "schema": {
              "type": "integer",
              "minimum": 100,
              "maximum": 80467,
              "default": 1609
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "1 to 200. Default 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Matching records, plus what was withheld and whether the point is covered.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "records",
                    "withheld",
                    "withheldReasons",
                    "covered"
                  ],
                  "properties": {
                    "records": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "jurisdiction": {
                            "type": "string",
                            "description": "Source jurisdiction code, e.g. us-fl."
                          },
                          "displayName": {
                            "type": "string"
                          },
                          "address": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "latitude": {
                            "type": "number"
                          },
                          "longitude": {
                            "type": "number"
                          },
                          "riskLevel": {
                            "type": "string"
                          },
                          "offenseSummary": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "sourceUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The entry on the originating registry, where it publishes one."
                          },
                          "lastUpdated": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "withheld": {
                      "type": "integer",
                      "description": "Records we hold for this area but did not serve for your declared purpose."
                    },
                    "withheldReasons": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "jurisdiction": {
                            "type": "string"
                          },
                          "citation": {
                            "type": "string"
                          },
                          "note": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "covered": {
                      "type": "boolean",
                      "description": "Whether we mirror a registry covering this point at all. False with an empty result means we cannot see here — not that nobody is here."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or unusable API key."
          },
          "429": {
            "description": "Monthly quota spent, or sustained rate exceeded. Not billed."
          }
        }
      }
    },
    "/v1/api/atlas": {
      "get": {
        "tags": [
          "atlas"
        ],
        "summary": "Registry law and coverage for every country",
        "description": "Our own research rather than a registry feed, so it carries no third-party use restriction. Each country carries its legal status, the operating body, the official name of the register, how an ordinary person checks, a citation and a verification date.",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by status: covered, public_not_integrated, no_public_registry, restricted, unverified.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One row per country.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "countries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "description": "ISO 3166-1 alpha-2, lowercased."
                          },
                          "status": {
                            "type": "string"
                          },
                          "note": {
                            "type": "string"
                          },
                          "source": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Primary-source citation."
                          },
                          "verifiedOn": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date"
                          },
                          "caveat": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "registerName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "operator": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "since": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "howToCheck": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "publishedTotal": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "The government's own published registrant total, where it publishes one. Null means no figure is published — never zero."
                          },
                          "publishedScope": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "publishedAsOf": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/api/jurisdictions/us": {
      "get": {
        "tags": [
          "atlas"
        ],
        "summary": "How each of the 56 US registries works",
        "description": "All 50 states, DC and the five territories. `addressPrecision` records what the public site PUBLISHES, not what the state knows. Null means we could not establish it, never that the state publishes nothing.",
        "responses": {
          "200": {
            "description": "One row per US registration jurisdiction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jurisdictions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "registerName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "operator": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "publicUrl": {
                            "type": "string"
                          },
                          "statute": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "tiering": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "addressPrecision": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "exact_address",
                              "block_or_street",
                              "zip_or_city",
                              "none",
                              null
                            ]
                          },
                          "includesJuveniles": {
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "searchableBy": {
                            "type": [
                              "array",
                              "null"
                            ],
                            "items": {
                              "type": "string"
                            }
                          },
                          "publicNotification": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "registrantCount": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Only where the jurisdiction publishes a figure about its own registry, carried with its scope and date."
                          },
                          "confidence": {
                            "type": "string",
                            "enum": [
                              "high",
                              "medium",
                              "low"
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/api/jurisdictions/us/{code}": {
      "get": {
        "tags": [
          "atlas"
        ],
        "summary": "One US jurisdiction in full",
        "description": "The full profile, with the permitted-use policy for that jurisdiction attached as `usePolicy`. Accepts a tribal registry code as well as a state code.",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "description": "Two-letter state or territory code.",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The jurisdiction, including its use policy."
          },
          "404": {
            "description": "No such jurisdiction."
          }
        }
      }
    },
    "/v1/api/jurisdictions/tribal": {
      "get": {
        "tags": [
          "atlas"
        ],
        "summary": "Tribal registration jurisdictions",
        "description": "Federally recognised tribes acting as SORNA registration jurisdictions in their own right. `ownRegistry: true` means the tribe publishes its own public search and the surrounding state's registry does NOT hold those records.",
        "responses": {
          "200": {
            "description": "Tribes, and how many publish their own registry.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tribes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "tribe": {
                            "type": "string"
                          },
                          "state": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "ownRegistry": {
                            "type": "boolean"
                          },
                          "publicUrl": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "withOwnRegistry": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/api/policy": {
      "get": {
        "tags": [
          "policy"
        ],
        "summary": "What your key may be used for, by jurisdiction",
        "description": "The permitted-use position for every jurisdiction we serve, and whether your own key's declared purpose can receive it. Published as an endpoint rather than buried in a clause because getting this wrong is your liability as well as ours.",
        "responses": {
          "200": {
            "description": "Your declared purpose, and the position for each jurisdiction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "yourPurpose": {
                      "type": "string"
                    },
                    "jurisdictions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "posture": {
                            "type": "string",
                            "enum": [
                              "open",
                              "restricted",
                              "prohibited",
                              "unreviewed"
                            ]
                          },
                          "citation": {
                            "type": "string"
                          },
                          "prohibitedPurposes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "note": {
                            "type": "string"
                          },
                          "servesYourPurpose": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/api/safeguarding": {
      "get": {
        "tags": [
          "atlas"
        ],
        "summary": "What a parent or employer can actually do, per country",
        "description": "For the countries with no public registry, the practical answer: the vetting certificate or barred list that does exist, and crucially who may request it. `independentlyVerified: false` means unaudited, not wrong.",
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "description": "Filter by scheme kind: child_specific_certificate, barred_list, general_criminal_record, police_disclosure_scheme.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One row per country.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "countries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string"
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "kind": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "operator": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "whoCanRequest": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "requiredFor": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "url": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "source": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "confidence": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "independentlyVerified": {
                            "type": "boolean"
                          },
                          "notEstablished": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Why no scheme is recorded. Never means the country has nothing — it means we did not establish one."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/api/safeguarding/{country}": {
      "get": {
        "tags": [
          "atlas"
        ],
        "summary": "One country's safeguarding check in full",
        "description": "Every field, including how to obtain the document and what it costs.",
        "parameters": [
          {
            "name": "country",
            "in": "path",
            "required": true,
            "description": "ISO 3166-1 alpha-2 code.",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The country's safeguarding entry."
          },
          "404": {
            "description": "No such country."
          }
        }
      }
    }
  }
}