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

# The Agency API

> Who this API is for, what it answers, and what it will not do

This is the agency side of the Turris API. If you are a carrier or MGA reading about the agencies you appoint, you want [The Carrier & MGA API](/guides/carrier-api) instead, and a credential works on exactly one of the two.

## Who it is for

**Agencies and brokerages**: organizations that hold licenses and place business, and need their own compliance record as data rather than as a screen. Your own entities and branches, your own producers, your own licenses and appointments, and the markets you place through.

Your credential is issued to one Turris organization and reaches `/v2/downstream/*`. On `/v2/upstream/*`, and on every persona-scoped `/v1/*` route, it returns **403** with `errorType` `invalid_organization_category`.

<Note>
  **Four routes are the exception, on both versions.** `POST /v{1,2}/auth/jwt`, `GET /v{1,2}/auth/test-oauth`, `GET /v{1,2}/auth/test-restricted-access-token` and `GET /v{1,2}/heartbeat` carry no persona and serve any credential, because the token itself identifies the organization. So the `v1` token endpoint works for you; everything you would then call with that token does not. Prefer the `v2` paths regardless, since only `GET /v2/auth/test-oauth` reports `orgCategory`.
</Note>

<Note>
  **This surface is `v2` only.** `v1` predates the persona model and serves carriers exclusively, so there is no `v1` agency surface and there will not be one. Nothing is missing from your surface as a result: `v2` is where it was born.
</Note>

## What it answers

<CardGroup cols={2}>
  <Card title="Your organization" icon="sitemap" href="/api-reference/v2/downstream/entities/list-entities">
    Your legal entities and branches, the producers attached to them, and your contacts. Call `entities` first: most other endpoints take a `downstreamEntityId` and this is where those ids come from.
  </Card>

  <Card title="Licenses and appointments" icon="id-card" href="/api-reference/v2/downstream/licenses/entity-licenses">
    State licenses and lines of authority for both your entities and your producers, plus appointment records, all synced from NIPR.
  </Card>

  <Card title="What needs attention today" icon="bell" href="/api-reference/v2/downstream/actions-required">
    The one endpoint to poll on a schedule. Expiring and expired licenses across your whole organization, in one list.
  </Card>

  <Card title="Licensing overview" icon="chart-simple" href="/api-reference/v2/downstream/license-overview/entity-license-summary">
    The aggregates behind the dashboard: counts and coverage per entity and per producer, rather than raw license rows.
  </Card>

  <Card title="Your markets" icon="handshake" href="/api-reference/v2/downstream/markets/list-markets">
    The carriers, MGAs and wholesalers you place business with, their contacts, and the documents shared on each relationship.
  </Card>

  <Card title="Corporate registrations" icon="stamp" href="/api-reference/v2/downstream/corporate-registrations/list-filings">
    State registration filings and the standing facts behind them.
  </Card>

  <Card title="Documents" icon="file" href="/api-reference/v2/downstream/documents/list-documents">
    Compliance policies, their status per entity, and uploads.
  </Card>

  <Card title="Renewal work in flight" icon="file-signature" href="/api-reference/v2/downstream/license-requests/list-license-requests">
    The license requests Turris is running on your behalf, and the groups they belong to.
  </Card>
</CardGroup>

## The one thing to understand before you build

**Your credential sees its own organization plus everything beneath it, and never anything above it.**

<CardGroup cols={2}>
  <Card title="Minted at your top company" icon="sitemap">
    You see the top company and every branch. This is what most integrations want.
  </Card>

  <Card title="Minted at a branch" icon="code-branch">
    You see that branch and nothing else. Not the parent, not sibling branches, even though a person signed into that branch in the web application can see them.
  </Card>
</CardGroup>

This is narrower than what the agency application shows a branch user, on purpose. A leaked branch credential must not read the whole group. Widening a scope later adds rows to a response while narrowing one removes them, so we started on the side that can move. **If your integration covers the whole group, mint the credential at the top company.**

An id outside your scope returns **404**, not 403. A 403 would confirm that the entity exists, which is the same disclosure in a politer envelope. Treat a 404 on an id you believe is yours as a sign the credential was minted lower in the tree than you thought.

## What it will not do

<AccordionGroup>
  <Accordion title="Send you webhooks">
    Webhooks are a carrier feature. The events fire about an agency a carrier appoints, and only a carrier credential can subscribe. There is no `/v2/downstream/webhooks` and no agency equivalent.

    Poll [Actions Required](/api-reference/v2/downstream/actions-required) and the [licensing summaries](/api-reference/v2/downstream/license-overview/entity-license-summary) on a schedule instead. Tell us if a subscription would be more useful.
  </Accordion>

  <Accordion title="Return a document download URL">
    Document endpoints return metadata and version history. No presigned URL is returned and there is no document endpoint that mints one, on either surface.

    The one exception is a completed surplus-lines filing: [Get a Filing](/api-reference/v2/downstream/surplus-lines-filings/get-filing) returns `downloadUrl` and `viewUrl` on its completion artifact.
  </Accordion>

  <Accordion title="Reach anything above you in the tree">
    Not your parent company, not sibling branches, and never another agency. See credential scope above.
  </Accordion>

  <Accordion title="Show you a carrier's own compliance data">
    A market record tells you about your relationship with that carrier, its contacts and the documents shared on it. It is not a window into the carrier's organization.
  </Accordion>

  <Accordion title="Accept downstreamEntityId on three market sub-lists">
    Almost every list narrows by `downstreamEntityId`. The three exceptions are the market sub-lists, `/markets/{upstreamDownstreamAssociationId}/documents`, `/entity-contacts` and `/market-contacts`, which take only the association id plus `page` and `limit`.
  </Accordion>
</AccordionGroup>

## Make your first call

<Steps>
  <Step title="Get credentials">
    **Settings → API** in the agency application, in the environment you intend to integrate against. Sandbox first. If that section is not in your navigation, your organization is not entitled yet; contact [support@turrisfi.com](mailto:support@turrisfi.com).
  </Step>

  <Step title="Exchange them for a token">
    ```bash theme={null}
    curl -X POST "https://public.api.sandbox.turrisfi.com/v2/auth/jwt" \
      -H "Content-Type: application/json" \
      -d '{ "clientId": "your-client-id", "clientSecret": "your-client-secret" }'
    ```

    Tokens last 60 minutes. **Cache them.** The token endpoint allows 4 requests per window, so a client that fetches a fresh token per call starts failing almost immediately.
  </Step>

  <Step title="Read your entities">
    ```bash theme={null}
    curl "https://public.api.sandbox.turrisfi.com/v2/downstream/entities" \
      -H "Authorization: Bearer <your-jwt-token>"
    ```

    Start here rather than anywhere else. The `downstreamEntityId` values in this response are what the rest of the surface takes.
  </Step>
</Steps>

[Getting Started for Agencies](/guides/downstream-getting-started) covers credentials, scope and per-area entitlement in full.

## Vocabulary, before you read the reference

Most of this surface speaks your language. Three names are worth knowing because they are not the words you would guess:

| Your word                                      | The API's word                                                                                                            |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Your company or a branch                       | A **licensed entity** in navigation, a **legal entity** in prose, `entities` in the URL, `downstreamEntityId` in payloads |
| A carrier, MGA or wholesaler you place through | A **market**, identified by `upstreamDownstreamAssociationId`, not `marketId`                                             |
| A licensed individual at your agency           | A **producer** on this surface. The carrier surface calls the same person an **agent**                                    |

The [full mapping between the two surfaces' vocabularies](/which-api-is-mine#the-same-records-two-vocabularies) is on one page if you ever compare notes with a carrier.

## Entitlement

Each area of this API needs the same product feature as the matching screen in the agency application. API access opens the door; it does not grant an area your organization has not bought. If you can see a section in the app, its endpoints are available to your credential. If you cannot, they return **403** with `errorType` `product_feature_subscription_required` and a message naming the feature to ask for.

A 403 on one area never affects the others: the rest of your integration keeps working. The [full endpoint-to-feature table](/guides/downstream-getting-started#1-check-your-organization-is-entitled) is in the getting-started guide.

## Before you go to production

<AccordionGroup>
  <Accordion title="Every list is paginated">
    `items`, `total`, `page`, `limit`, `totalPages`. Default 50, maximum 100. See [Pagination](/guides/pagination).
  </Accordion>

  <Accordion title="Send an idempotency key on every write">
    All seven `POST` operations on this surface accept an `Idempotency-Key` header and replay the original response for an hour. Without one, a retried request runs twice. See [Idempotency](/guides/idempotency).
  </Accordion>

  <Accordion title="Rate limits are per organization">
    120 reads and 30 writes per minute, counted per endpoint and per organization rather than per IP address. See [Rate Limiting](/guides/rate-limiting).
  </Accordion>

  <Accordion title="Branch on errorType, not on message text">
    Messages are prose and may be reworded. The codes are a published enum. See [Error Handling](/guides/error-handling).
  </Accordion>
</AccordionGroup>


## Related topics

- [Getting Started for Agencies](/guides/downstream-getting-started.md)
- [The Carrier & MGA API](/guides/carrier-api.md)
- [Which API Is Mine?](/which-api-is-mine.md)
