> ## Documentation Index
> Fetch the complete documentation index at: https://docs.canary.effectiveai.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Research regulatory documents

> Find US insurance statutes, regulations, bulletins, orders and bills, read their text, follow citations, and compare form checklist requirements across states.

Follow [connection setup](/guides/index#connect-once) first. You need permission to view SERFF
filings and regulatory documents; read-only keys work. Regulatory documents are part of the base
data, so no extra data access is needed.

The corpus holds statutes, regulations, bulletins, orders, bills, filing requirements, form
checklists and NAIC material for every state, DC, the territories, and national NAIC material
under the state code `ALL`.

## Choose an operation

| Question | Operation |
| - | - |
| Which documents are about this topic? | `GET /insurance/regulatory-documents` with `query` |
| Which documents match these filters, or what is new? | `GET /insurance/regulatory-documents` without `query` |
| What does one document say, and where is its source? | `GET /insurance/regulatory-documents/{documentId}` and its `/text` |
| What does it cite, and what cites it? | `GET /insurance/regulatory-documents/{documentId}/references` |
| What does each state require on a form, such as a notice? | `GET /insurance/regulatory-requirements` |

## Search by topic

Send `query` with words or a question. This search ranks Texas documents about cancellation
notices for commercial general liability:

```bash theme={null}
curl --request GET \
  --url "https://api.canary.effectiveai.app/api/v2/insurance/regulatory-documents?query=commercial%20general%20liability%20cancellation%20notice&state=TX&limit=1" \
  --header "Authorization: Bearer $EFFECTIVE_API_KEY"
```

```json Response (summary abbreviated) theme={null}
{
  "documents": [
    {
      "id": "351c780b-e92f-4e1a-b483-0b8ff51d949d",
      "state": "TX",
      "kind": "regulation",
      "identifier": "28 TAC § 5.7013",
      "title": "28 Tex. Admin. Code § 5.7013 - Notice Requirements for Cancellation and Nonrenewal for General Liability and Certain Automobile Insurance Policies",
      "status": "final",
      "publishedDate": "1986-10-03",
      "firstSeenAt": "2026-07-15T07:06:06.728230Z",
      "toiCodes": ["17.0", "19.4", "21.1"],
      "impactTags": ["underwriting", "market_conduct", "consumer_protection"],
      "summary": "This regulation establishes the mandatory notice requirements for the cancellation and nonrenewal of general liability, commercial automobile, and private passenger automobile insurance policies in Texas. ..."
    }
  ],
  "exhaustive": false,
  "nextCursor": "v1.Y2Vh..."
}
```

Results come from a window of the best 200 word matches and the best 200 meaning matches, so
`exhaustive` is always `false`: other documents can match. Follow `nextCursor` to page through
the window. Rankings can shift between pages when documents change. Results do not include the
matching passage; read the text to find it. `sort` is not allowed with `query`.

Search can take several seconds. If it fails, you get 503 `temporarily_unavailable`; wait for
`Retry-After`, or list the same filters without `query`.

## List with filters

Without `query`, the endpoint returns every matching document in a fixed order. Follow
`nextCursor` until it is null; `exhaustive` is `true`.

| Parameter | Meaning |
| - | - |
| `state` | Two-letter code, or `ALL` for national NAIC material. |
| `kind` | Document kind, such as `statute`, `regulation`, `bulletin`, `order`, `legislative_bill`, `form_checklist`. |
| `status` | Lifecycle status, such as `final`, `proposed`, `introduced` or `enacted`. Documents without one never match. |
| `toi` | Exact TOI value. `21.0` does not match `21.1`. `ALL` matches only documents tagged `ALL`. |
| `impact` | Impact tag, such as `rating`, `underwriting` or `forms`. |
| `identifier` | Exact publisher identifier. It can match several documents. |
| `publishedDateFrom`, `publishedDateTo` | Inclusive `YYYY-MM-DD` dates. They drop undated documents. |
| `firstSeenFrom` | Inclusive RFC 3339 timestamp on `firstSeenAt`. |
| `sort` | `-firstSeenAt` (default), `-publishedDate` or `identifier`. Missing values sort last. |
| `limit`, `cursor` | Page size (default 50, maximum 100) and the returned `nextCursor`. |

Repeat `state`, `kind`, `status`, `toi` or `impact` to supply alternatives, for example
`state=KS&state=MO`. Values within one filter are OR; different filters are AND. The API
reference lists every allowed `kind`, `status` and `impact` value. Unknown values and unknown
parameters return 400 `invalid_request`.

Statutes have no TOI or impact tags, and most orders have none. A `toi` or `impact` filter
leaves them out. TOI values also include `H` (health), `L` (life), `T` (title) and `ALL`.

## Watch for new documents

Poll with `firstSeenFrom` and the default `sort=-firstSeenAt`:

```bash theme={null}
curl --request GET \
  --url "https://api.canary.effectiveai.app/api/v2/insurance/regulatory-documents?state=KS&state=MO&kind=bulletin&firstSeenFrom=2026-10-01T00:00:00Z" \
  --header "Authorization: Bearer $EFFECTIVE_API_KEY"
```

```json Response (first document, abbreviated) theme={null}
{
  "documents": [
    {
      "id": "efd33d94-4338-4a28-9057-e2a5a7333133",
      "state": "MO",
      "kind": "bulletin",
      "identifier": "WC-Tax-2027",
      "title": "(2027) - Workers’ compensation administrative tax, Second Injury Fund surcharges and Administrative surcharge",
      "status": "final",
      "publishedDate": "2027-01-01",
      "firstSeenAt": "2026-10-09T01:30:29.921192Z",
      "toiCodes": ["16.0"],
      "impactTags": ["rating", "solvency", "data_reporting"],
      "summary": "The Missouri Department of Labor and Industrial Relations and the Department of Commerce and Insurance have announced the 2027 calendar year tax and surcharge rates. ..."
    }
  ],
  "exhaustive": true,
  "nextCursor": null
}
```

* Documents are stored in batches, so a document can appear after one with a later
  `firstSeenAt`. Start each poll a little before the previous one, and drop IDs you have seen.
* A backfill or a changed source page can make an old document look new. Check `publishedDate`.
* A bill that moves to another stage is not new. Its `status` changes in place.

## Read a document

```bash theme={null}
curl --request GET \
  --url "https://api.canary.effectiveai.app/api/v2/insurance/regulatory-documents/351c780b-e92f-4e1a-b483-0b8ff51d949d" \
  --header "Authorization: Bearer $EFFECTIVE_API_KEY"
```

```json Response (title and summary abbreviated) theme={null}
{
  "id": "351c780b-e92f-4e1a-b483-0b8ff51d949d",
  "state": "TX",
  "kind": "regulation",
  "identifier": "28 TAC § 5.7013",
  "title": "28 Tex. Admin. Code § 5.7013 - Notice Requirements for Cancellation and Nonrenewal ...",
  "status": "final",
  "publishedDate": "1986-10-03",
  "effectiveDate": null,
  "firstSeenAt": "2026-07-15T07:06:06.728230Z",
  "toiCodes": ["17.0", "19.4", "21.1"],
  "impactTags": ["underwriting", "market_conduct", "consumer_protection"],
  "summary": "This regulation establishes the mandatory notice requirements ...",
  "legalRefs": [
    "28 TAC § 5.7013",
    "Insurance Code § 551.053",
    "28 TAC § 5.7014",
    "Insurance Code § 551.054",
    "Insurance Code § 551.1053"
  ],
  "sourceUrl": "https://www.law.cornell.edu/regulations/texas/28-Tex-Admin-Code-SS-5-7013",
  "fileId": null
}
```

* `publishedDate` is the publisher's date as stored. It can be missing or wrong, and a year-only
  date is stored as 1 January.
* `toiCodes`, `impactTags` and `legalRefs` are null when the document was never classified, and
  `[]` when it was classified and none apply.
* `summary` is a research aid, not the source. Most documents have none.
* `fileId` is the stored source file, when there is one. Download it with
  [Read and cite document evidence](/guides/read-filing-documents).

## Read the text

Read the stored text in chunks, with the same contract as file text:

```bash theme={null}
curl --request GET \
  --url "https://api.canary.effectiveai.app/api/v2/insurance/regulatory-documents/351c780b-e92f-4e1a-b483-0b8ff51d949d/text?maxBytes=200" \
  --header "Authorization: Bearer $EFFECTIVE_API_KEY"
```

```json Response theme={null}
{
  "documentId": "351c780b-e92f-4e1a-b483-0b8ff51d949d",
  "textRevision": "rt1.2cea7a4b2999418895c11f93320fc054fbb325c6d810e631e6c8e6aac11a4ec5",
  "text": "(a) An insurer may cancel general liability insurance policies and commercial automobile insurance policies to which this section applies by providing the notice required by Insurance Code § 551.053,",
  "location": { "startOffsetBytes": 0, "endOffsetBytes": 200 },
  "nextCursor": "v1.PbQ2..."
}
```

Continue with the same `maxBytes` and `cursor={nextCursor}` until `nextCursor` is null. Offsets
count UTF-8 bytes. Documents are updated in place: when the text changes, an old cursor returns
400 `invalid_cursor`; start again without a cursor. A document with no text returns 409
`text_unavailable`. Text taken from PDFs can lose tables and layout, so the source file stays the
evidence.

## Follow citations

List what a document cites:

```bash theme={null}
curl --request GET \
  --url "https://api.canary.effectiveai.app/api/v2/insurance/regulatory-documents/351c780b-e92f-4e1a-b483-0b8ff51d949d/references?limit=1" \
  --header "Authorization: Bearer $EFFECTIVE_API_KEY"
```

```json Response theme={null}
{
  "references": [
    {
      "relationship": "references",
      "citation": "Tex. Ins. Code § 551.053",
      "document": {
        "id": "3de80c5e-396d-4e42-9bd3-766b8587e18a",
        "state": "TX",
        "kind": "statute",
        "identifier": "insurance-code__title-5__subtitle-c__chapter-551__subchapter-b__section-551-053"
      }
    }
  ],
  "nextCursor": "v1.u9Zk..."
}
```

`relationship` is `references`, `amends` or `supersedes`. `citation` is the citation as written.
`document` is the cited document, or null when it is not in the corpus. Add `direction=in` to list
documents that cite this one. A document can cite laws in `legalRefs` without reference rows.

## Compare form requirements across states

Form checklists have requirement items. List the Kansas commercial auto items for cancellation
notices:

```bash theme={null}
curl --request GET \
  --url "https://api.canary.effectiveai.app/api/v2/insurance/regulatory-requirements?state=KS&formType=CANCELLATION_NOTICE&toi=21.0&limit=1" \
  --header "Authorization: Bearer $EFFECTIVE_API_KEY"
```

```json Response theme={null}
{
  "requirements": [
    {
      "id": "c892a541-bdf3-4ece-aaa6-6eb8eac5b223",
      "document": {
        "id": "8a2997c5-ab5f-4e20-86c9-368afcaccdae",
        "state": "KS",
        "title": "Commercial Auto Filing Checklist"
      },
      "requirement": "The insurer must send any unearned premium to the consumer along with the cancellation notice.",
      "sourceText": "Any unearned premium must be sent to the consumer with the cancellation notice.",
      "category": "DELIVERY",
      "scope": "FORM",
      "formTypes": ["CANCELLATION_NOTICE"],
      "actions": ["CANCELLATION"],
      "toiCodes": ["21.0", "21.1"],
      "legalRefs": ["K.A.R. 40-1-17", "K.S.A. 40-3118"],
      "sourceLocator": { "heading": "PREMIUM REFUND OR RETENTION", "chunkIndex": 5 }
    }
  ],
  "nextCursor": "v1.3fXa..."
}
```

Repeat `state` to compare states in one list, or use `document` with a checklist ID for one
checklist. Other filters are `formType`, `action`, `category` and `toi`. Results are ordered by
state, checklist and category, with no totals. Check `sourceText` against the checklist before you
rely on an item: items are checklist evidence, not legal authority. Read the checklist with its
`document.id`.

## Handle errors

| Response | Meaning and next step |
| - | - |
| 400 `invalid_request` | Fix the request: an unknown value, `sort` with `query`, or a `limit` above 100. |
| 400 `invalid_cursor` | The cursor expired, the query changed, or the text changed. Start again without a cursor. |
| 404 `not_found` | The document or item is gone. A duplicate cleanup can delete a document; search again. |
| 409 `text_unavailable` | The document has no text. Use its `sourceUrl` or `fileId`. |
| 503 `temporarily_unavailable` | Wait for `Retry-After`, then retry with backoff. |

Cursors expire 24 hours after the first page. Repeat the same parameters and `limit` with each
cursor.

## Cost

* A search with `query` costs $0.02 plus $0.003 per returned document. A page of 50 costs \$0.17.
* A list without `query` costs $0.003 per returned document, and a document read costs $0.003.
* Each text chunk costs \$0.01, including each continuation.
* Each citation row costs \$0.003.
* Each requirement item costs \$0.01, in a list or a single read.
* Empty pages and failed calls are free. Repeating a successful call is charged again.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.