{
  "openapi": "3.1.0",
  "info": {
    "title": "Regbase API (v1)",
    "version": "v1",
    "description": "JSON:API surface for warehouse entities and the entity change feed.\n\nResponses use `application/vnd.api+json`. CORS allows any origin.\n\nEntity and change endpoints require an organization API key in the\n`Authorization: Bearer` header. Create keys in your Regbase account\nsettings.\n\nEntity resources lift the warehouse `type` to the JSON:API resource `type`\n(for example `legislation` or `person`) and spread remaining fields into\n`attributes`. Empty snapshots fall back to resource type `entity`.\n\nMerged entities are followed to the surviving canonical id (up to 5 hops).\n\n### Field contract\n\nGFFS filters and returned attributes are limited to:\n\n`type, title, name, displayDate, jurisdiction, localIdentifier, localType, authority, status`\n\n`type` is the JSON:API resource type, not an attribute. `changedKeys` on\nchange resources is intersected with this set plus `texts`. Entity responses\nalso include `texts` with Public Text IDs and downloadable renditions."
  },
  "servers": [
    {
      "url": "https://api.regbase.com"
    }
  ],
  "tags": [
    {
      "name": "Entities",
      "description": "List and look up warehouse entities."
    },
    {
      "name": "Renditions",
      "description": "Download entity document renditions."
    },
    {
      "name": "Changes",
      "description": "Tail material entity changes with a GFFS filter."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "Organization API key. Send `Authorization: Bearer rb_live_…`."
      }
    },
    "schemas": {
      "EntityAttributes": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "displayDate": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string"
          },
          "localIdentifier": {
            "type": "string"
          },
          "localType": {
            "type": "string"
          },
          "authority": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "texts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "textId": {
                  "type": "string",
                  "pattern": "^txt_[0-9a-f]{32}$"
                },
                "localUrl": {
                  "type": "string"
                },
                "date": {
                  "type": "string"
                },
                "mime": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "renditions": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "renditionId": {
                        "type": "string",
                        "pattern": "^rnd_[0-9a-f]{32}$"
                      },
                      "conversion": {
                        "type": "string"
                      },
                      "language": {
                        "type": "string"
                      },
                      "mime": {
                        "type": "string"
                      },
                      "filename": {
                        "type": "string"
                      },
                      "fetchedUrl": {
                        "type": "string",
                        "format": "uri"
                      },
                      "links": {
                        "type": "object",
                        "properties": {
                          "content": {
                            "type": "string",
                            "format": "uri"
                          }
                        },
                        "required": [
                          "content"
                        ]
                      }
                    },
                    "required": [
                      "renditionId",
                      "conversion",
                      "mime",
                      "filename",
                      "links"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "renditions"
              ],
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false,
        "description": "v1 discovery attributes. `type` is the resource type, not an attribute."
      },
      "EntityResource": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Domain type from the snapshot (for example `legislation`). Empty snapshots use `entity`."
          },
          "id": {
            "type": "string",
            "description": "Canonical entity id."
          },
          "attributes": {
            "$ref": "#/components/schemas/EntityAttributes"
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "self"
            ]
          }
        },
        "required": [
          "type",
          "id",
          "attributes"
        ]
      },
      "EntityCollectionDocument": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityResource"
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "format": "uri"
              },
              "next": {
                "type": "string",
                "format": "uri",
                "description": "Present when another page of matching entities exists."
              }
            },
            "required": [
              "self"
            ]
          },
          "meta": {
            "type": "object",
            "properties": {
              "cursor": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Id of the last entity on the page. Pass as `page[after]`."
              }
            },
            "required": [
              "cursor"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "data",
          "links",
          "meta"
        ]
      },
      "JsonApiErrorDocument": {
        "type": "object",
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "detail": {
                  "type": "string"
                },
                "code": {
                  "type": "string"
                },
                "source": {
                  "type": "object",
                  "properties": {
                    "parameter": {
                      "type": "string"
                    },
                    "pointer": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "required": [
          "errors"
        ]
      },
      "EntityDocument": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/EntityResource"
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "self"
            ]
          }
        },
        "required": [
          "data",
          "links"
        ]
      },
      "EntityChangeAttributes": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "displayDate": {
            "type": "string"
          },
          "jurisdiction": {
            "type": "string"
          },
          "localIdentifier": {
            "type": "string"
          },
          "localType": {
            "type": "string"
          },
          "authority": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "texts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "textId": {
                  "type": "string",
                  "pattern": "^txt_[0-9a-f]{32}$"
                },
                "localUrl": {
                  "type": "string"
                },
                "date": {
                  "type": "string"
                },
                "mime": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "renditions": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "renditionId": {
                        "type": "string",
                        "pattern": "^rnd_[0-9a-f]{32}$"
                      },
                      "conversion": {
                        "type": "string"
                      },
                      "language": {
                        "type": "string"
                      },
                      "mime": {
                        "type": "string"
                      },
                      "filename": {
                        "type": "string"
                      },
                      "fetchedUrl": {
                        "type": "string",
                        "format": "uri"
                      },
                      "links": {
                        "type": "object",
                        "properties": {
                          "content": {
                            "type": "string",
                            "format": "uri"
                          }
                        },
                        "required": [
                          "content"
                        ]
                      }
                    },
                    "required": [
                      "renditionId",
                      "conversion",
                      "mime",
                      "filename",
                      "links"
                    ],
                    "additionalProperties": false
                  }
                }
              },
              "required": [
                "renditions"
              ],
              "additionalProperties": false
            }
          },
          "changeType": {
            "type": "string",
            "enum": [
              "create",
              "update",
              "delete",
              "merge"
            ]
          },
          "changedKeys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Top-level public snapshot keys that changed, including texts and v1 discovery fields."
          },
          "mergedInto": {
            "type": [
              "string",
              "null"
            ],
            "description": "Id of the surviving entity when `changeType` is `merge`."
          },
          "recordedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "changeType",
          "changedKeys",
          "mergedInto",
          "recordedAt"
        ],
        "additionalProperties": false
      },
      "JsonApiResourceIdentifier": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string"
          },
          "id": {
            "type": "string"
          }
        },
        "required": [
          "type",
          "id"
        ],
        "additionalProperties": false
      },
      "EntityChangeResource": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "entity-change"
            ]
          },
          "id": {
            "type": "string",
            "description": "Change id (`echg_…`)."
          },
          "attributes": {
            "$ref": "#/components/schemas/EntityChangeAttributes"
          },
          "relationships": {
            "type": "object",
            "properties": {
              "entity": {
                "type": "object",
                "properties": {
                  "data": {
                    "$ref": "#/components/schemas/JsonApiResourceIdentifier"
                  },
                  "links": {
                    "type": "object",
                    "properties": {
                      "related": {
                        "type": "string",
                        "format": "uri",
                        "description": "GET /v1/entities/{id}"
                      }
                    },
                    "required": [
                      "related"
                    ]
                  }
                },
                "required": [
                  "data",
                  "links"
                ]
              }
            },
            "required": [
              "entity"
            ]
          }
        },
        "required": [
          "type",
          "id",
          "attributes",
          "relationships"
        ]
      },
      "EntityChangesDocument": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityChangeResource"
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "format": "uri"
              },
              "next": {
                "type": "string",
                "format": "uri",
                "description": "Present when another page of matching changes may exist."
              }
            },
            "required": [
              "self"
            ]
          },
          "meta": {
            "type": "object",
            "properties": {
              "cursor": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Pass as `page[after]` to continue. Advances even on empty pages."
              }
            },
            "required": [
              "cursor"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "data",
          "links",
          "meta"
        ]
      },
      "EntitySearchDocument": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EntityResource"
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "self": {
                "type": "string",
                "format": "uri"
              }
            },
            "required": [
              "self"
            ]
          }
        },
        "required": [
          "data",
          "links"
        ]
      }
    },
    "parameters": {}
  },
  "paths": {
    "/v1/entities": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "List entities",
        "operationId": "listEntities",
        "description": "Returns canonical entities (not drained or merged, not empty snapshots) ordered by id. Optional GFFS qualifier string. Omit to list all entities. Free-text terms are rejected. Allowed fields: type, title, name, displayDate, jurisdiction, localIdentifier, localType, authority, status.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Optional GFFS qualifier string. Omit to list all entities. Free-text terms are rejected. Allowed fields: type, title, name, displayDate, jurisdiction, localIdentifier, localType, authority, status.",
              "example": "jurisdiction:US.CA status:Passed"
            },
            "required": false,
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Entity id cursor from the previous page's `meta.cursor`."
            },
            "required": false,
            "name": "page[after]",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "description": "Page size. Default 100, maximum 100."
            },
            "required": false,
            "name": "page[limit]",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Entity collection",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityCollectionDocument"
                }
              }
            }
          },
          "400": {
            "description": "Invalid `filter`, unsupported field, nested path, free-text term, or invalid pagination.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          }
        }
      }
    },
    "/v1/entities/{id}": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Get an entity by id",
        "operationId": "getEntity",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-z]+$",
              "description": "Entity id (`[0-9a-z]+`)."
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Entity document",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityDocument"
                }
              }
            }
          },
          "400": {
            "description": "Invalid entity id.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "404": {
            "description": "Entity not found, including drained merge sources past the hop limit.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          }
        }
      }
    },
    "/v1/entities/changes": {
      "get": {
        "tags": [
          "Changes"
        ],
        "summary": "List entity changes",
        "operationId": "listEntityChanges",
        "description": "Change resources use type `entity-change`. Snapshot fields are spread into\n`attributes` alongside `changeType`, `changedKeys`, `mergedInto`, and `recordedAt`.\nThe `entity` relationship uses the domain type from the snapshot.\n\n`meta.cursor` advances even when a filtered page is empty, so clients do not\nre-scan the same non-matching window. `links.next` is present when another page\nof matching changes may exist.\n\nGFFS qualifier string. Free-text terms are rejected. Allowed fields: type, title, name, displayDate, jurisdiction, localIdentifier, localType, authority, status. Change metadata (changeType, changedKeys, recordedAt) is not filterable. Operators: equality / multi-value OR, `~` contains, `>`, `>=`, `<`, `<=`, `..` ranges, and leading `-` negation (where valid). Filters apply to the post-change snapshot. Tombstones (empty entity) typically do not match.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "GFFS qualifier string. Free-text terms are rejected. Allowed fields: type, title, name, displayDate, jurisdiction, localIdentifier, localType, authority, status. Change metadata (changeType, changedKeys, recordedAt) is not filterable. Operators: equality / multi-value OR, `~` contains, `>`, `>=`, `<`, `<=`, `..` ranges, and leading `-` negation (where valid). Filters apply to the post-change snapshot. Tombstones (empty entity) typically do not match.",
              "example": "jurisdiction:US.CA status:Passed"
            },
            "required": true,
            "name": "filter",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Opaque change id cursor (`echg_…`) from the previous page's `meta.cursor`."
            },
            "required": false,
            "name": "page[after]",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "description": "Page size. Default 100, maximum 100."
            },
            "required": false,
            "name": "page[limit]",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Change page",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityChangesDocument"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid `filter`, unsupported field, nested path, free-text term, or invalid pagination.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search": {
      "get": {
        "tags": [
          "Entities"
        ],
        "summary": "Search entities",
        "operationId": "searchEntities",
        "description": "Parses `q` as GFFS. Field qualifiers are applied as static filters before ranking. Remaining text uses reciprocal-rank fusion of full-text and semantic vector search. A qualifier-only query returns up to 100 matching entities without hybrid ranking. Allowed qualifier fields: type, title, name, displayDate, jurisdiction, localIdentifier, localType, authority, status.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "GFFS query. Top-level field qualifiers are applied before ranking; remaining text is ranked with full-text and semantic vector search.",
              "example": "jurisdiction:US.CA \"clean energy\""
            },
            "required": true,
            "name": "q",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/EntitySearchDocument"
                }
              }
            }
          },
          "400": {
            "description": "Missing or invalid `q`, unsupported field, or nested field path.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "500": {
            "description": "Embedding or entity search failed.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          }
        }
      }
    },
    "/v1/entities/{id}/renditions/{renditionId}.{extension}": {
      "get": {
        "tags": [
          "Renditions"
        ],
        "summary": "Download a document rendition",
        "operationId": "getEntityRenditionContent",
        "description": "Returns the raw bytes for a rendition using its Public Rendition ID. `Content-Type` matches the rendition's `mime` attribute (for example `application/pdf`, `text/html`, or `text/plain`).",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-z]+$",
              "description": "Entity id (`[0-9a-z]+`)."
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^rnd_[0-9a-f]{32}$",
              "description": "Public Rendition ID (`rnd_` followed by 32 hex characters)."
            },
            "required": true,
            "name": "renditionId",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[a-z0-9]+$",
              "description": "File extension from the rendition content link, identifying its media type."
            },
            "required": true,
            "name": "extension",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Rendition bytes. Media type is the rendition `mime` value from the list response.",
            "headers": {
              "Content-Type": {
                "description": "The rendition MIME type.",
                "schema": {
                  "type": "string",
                  "example": "application/pdf"
                }
              },
              "Content-Language": {
                "description": "The rendition language, when known, as a BCP 47 language tag.",
                "schema": {
                  "type": "string",
                  "example": "en"
                }
              }
            },
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "description": "Invalid entity id or rendition id.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "404": {
            "description": "Entity or rendition not found.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded.",
            "content": {
              "application/vnd.api+json": {
                "schema": {
                  "$ref": "#/components/schemas/JsonApiErrorDocument"
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
