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

# Schema reference

> Every type of AIP, generated from spec/schema.ts and registry/src/schema.ts.

Every type of AIP draft 0.1, generated from [`spec/schema.ts`](https://github.com/Agentic-Insurance-Foundation/agentic-insurance-protocol/blob/main/spec/schema.ts) and the registry server's [`registry/src/schema.ts`](https://github.com/Agentic-Insurance-Foundation/agentic-insurance-protocol/blob/main/registry/src/schema.ts) through [`schema.json`](https://agenticinsuranceprotocol.org/schemas/0.1/schema.json). The sections follow `spec/schema.ts`, then `registry/src/schema.ts` from R1. The rules in the descriptions use the RFC 2119 keywords.

## 1. Identity of the extension

### `ConformanceLevel`

Conformance level that a seller declares.

* 1 Inform: `get_distributor`, `list_products`
* 2 Quote: level 1, plus `quote`
* 3 Subscribe: level 2, plus `submit_application` and `get_operation`

A server that declares a level MUST implement every tool of that level and of the levels below it.

Type: one of `1`, `2`, `3`.

### `AipSettings`

Settings object of the extension. A server puts it under `capabilities.extensions["org.agenticinsuranceprotocol/aip"]` in its MCP `server/discover` response, and in its [`AipDocument`](#aipdocument).

| Field | Type | Required | Description |
| - | - | - | - |
| `version` | string | Yes | Protocol version the server implements, "major.minor", for example "0.1". Until 1.0, a client MUST treat a different minor version as a different protocol. |
| `conformance_level` | [`ConformanceLevel`](#conformancelevel) | Yes | |
| `lines` | list of [`ProductLine`](#productline) | Yes | Product lines the server can quote. |
| `countries` | list of [`CountryCode`](#countrycode) | Yes | Countries where the server's products are sold. |

### `AipDocument`

The AIP document of a seller, at `https://{domain}/.well-known/aip.json`. It leads from a domain to its MCP server. The seller MUST serve it from that host, with no redirect to another host, so that the document proves that the seller controls the domain.

| Field | Type | Required | Description |
| - | - | - | - |
| `domain` | string | Yes | The domain that serves this document. |
| `mcp_url` | [`Url`](#url) | Yes | MCP endpoint of the server. |
| `aip` | [`AipSettings`](#aipsettings) | Yes | |

## 2. Common types

### `CountryCode`

ISO 3166-1 alpha-2 country code, upper case.

Type: string. Pattern: `^[A-Z]{2}$`.

### `SubdivisionCode`

ISO 3166-2 subdivision code, upper case, for example "US-CA" for California.

Type: string. Pattern: `^[A-Z]{2}-[A-Z0-9]{1,3}$`.

### `CurrencyCode`

ISO 4217 currency code.

Type: string. Pattern: `^[A-Z]{3}$`.

### `Lei`

Legal Entity Identifier (ISO 17442): 18 letters or digits, then 2 check digits.

Type: string. Pattern: `^[A-Z0-9]{18}[0-9]{2}$`.

### `LanguageTag`

BCP 47 language tag, for example `fr` or `en-GB`.

Type: string. Pattern: `^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})*$`.

### `DateString`

Calendar date, ISO 8601.

Type: string (date).

### `DateTimeString`

Date and time with offset, ISO 8601.

Type: string (date-time).

### `Url`

Type: string (uri).

### `Decimal`

A decimal number as a string, so that no value is lost to floating point, for example "12.90".

Type: string. Pattern: `^-?[0-9]+(\.[0-9]+)?$`.

### `Money`

| Field | Type | Required | Description |
| - | - | - | - |
| `amount` | [`Decimal`](#decimal) | Yes | |
| `currency` | [`CurrencyCode`](#currencycode) | Yes | |

### `ProductLine`

Product line. Servers SHOULD use a value of [`KnownProductLine`](#knownproductline). Other values MUST be lower case with underscores.

Type: string. Pattern: `^[a-z][a-z0-9_]*$`.

### `KnownProductLine`

Common product lines.

Type: one of `pet`, `home`, `renters`, `motor`, `travel`, `health`, `life`, `funeral`, `borrower_insurance`, `professional_liability`, `general_liability`, `business_owners_policy`, `workers_compensation`.

### `InsuredFamily`

Family of what a product insures: a kind of person, or a kind of good. Servers SHOULD use a value of [`KnownInsuredFamily`](#knowninsuredfamily). Other values MUST be lower case with underscores.

Type: string. Pattern: `^[a-z][a-z0-9_]*$`.

### `KnownInsuredFamily`

Families that the known product lines need.

Type: one of `person`, `organisation`, `pet`, `dwelling`, `contents`, `vehicle`.

## 3. Distributor (level 1)

### `DistributorRole`

Role of a party in the distribution chain. The provider roles are in [`ProviderRole`](#providerrole).

Type: [`ProviderRole`](#providerrole) or `broker` or `agent` or `mga` or `comparator`.

### `RegisterIdentifierType`

Kind of public register identifier.

Type: one of `orias_number`, `siren`, `fca_frn`, `npn`, `naic_cocode`, `lei`, `other`.

### `Licence`

One entry in a public register that gives the right to sell a product, or to carry its risk.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | |
| `regulator` | string | Yes | Supervising authority, for example "ACPR", "FCA", or a US state insurance department. |
| `register` | string | Yes | Name of the public register, for example "ORIAS", "REGAFI", "FCA Register", "NIPR". |
| `identifier_type` | [`RegisterIdentifierType`](#registeridentifiertype) | Yes | |
| `identifier` | string | Yes | |
| `role` | [`DistributorRole`](#distributorrole) | Yes | |
| `categories` | list of string | | Register categories, for example ORIAS "COA" (insurance broker) or "AGA" (tied insurance agent). |
| `subdivisions` | list of [`SubdivisionCode`](#subdivisioncode) | | Subdivisions where the licence applies, for example US states as ISO 3166-2 codes ("US-CA"). Omit when the licence covers the whole country. |
| `verification_url` | [`Url`](#url) | | Public page where anyone can check the entry. |

### `GetDistributorParams`

Params of `get_distributor`. No params.

Type: object.

### `GetDistributorResult`

| Field | Type | Required | Description |
| - | - | - | - |
| `legal_name` | string | Yes | |
| `trading_name` | string | | |
| `domain` | string | Yes | Domain the seller controls. It MUST match the server's own domain. |
| `lei` | [`Lei`](#lei) | | Legal Entity Identifier, when the seller has one. The registry uses it to match one company across registers. |
| `roles` | list of [`DistributorRole`](#distributorrole) | Yes | |
| `licences` | list of [`Licence`](#licence) | Yes | Every licence the seller relies on to sell the listed products. |
| `countries` | list of [`CountryCode`](#countrycode) | Yes | |
| `complaints_url` | [`Url`](#url) | | Where a customer can complain. Required by most regulators. |
| `aip` | [`AipSettings`](#aipsettings) | Yes | Settings the server declares for AIP. |

## 4. Products and documents (level 1)

### `ProviderRole`

Role of the party that carries the risk.

Type: `insurer`.

### `ProviderRef`

The party that carries the risk.

| Field | Type | Required | Description |
| - | - | - | - |
| `name` | string | Yes | |
| `legal_name` | string | | |
| `role` | [`ProviderRole`](#providerrole) | Yes | |
| `domain` | string | | Domain the provider controls, so that an agent can find it in the registry. |
| `lei` | [`Lei`](#lei) | | Legal Entity Identifier, when the provider has one. |
| `licences` | list of [`Licence`](#licence) | Yes | The register entries that allow the provider to carry the risk, for example its authorisation as an insurer. At least one. |

### `Product`

| Field | Type | Required | Description |
| - | - | - | - |
| `product_id` | string | Yes | |
| `name` | string | Yes | |
| `line` | [`ProductLine`](#productline) | Yes | |
| `provider` | [`ProviderRef`](#providerref) | | Provider of the product, when it is not the seller. |
| `underwriting_scope` | [`UnderwritingScope`](#underwritingscope) | Yes | The risks the product can cover. A product MUST publish it. |
| `summary` | string | Yes | |
| `tiers` | list of [`ProductTier`](#producttier) | Yes | The tiers of the product, each with its cover and no price, for example "Bronze", "Silver" and "Gold". A product with one level of cover has one tier. `quote` gives one offer for each tier that can cover the customer. |
| `options` | list of [`ProductOption`](#productoption) | | Options the customer can add to a tier (optional covers, extra services). |
| `documents` | list of [`InsuranceDocument`](#insurancedocument) | Yes | The documents of the product, such as the IPID and the general conditions. |

### `ProductTier`

One level of cover of a product. The price comes only from `quote`, because it depends on the customer.

| Field | Type | Required | Description |
| - | - | - | - |
| `key` | string | Yes | Stable key, unique in the product, for example "gold". [`Offer.tier`](#offer) gives it. |
| `name` | string | Yes | Name of the tier, for example "Gold", "Tous risques" or "Band B". |
| `summary` | string | | What the tier is for, in plain words. |
| `cover` | [`CoverSummary`](#coversummary) | Yes | |

### `UnderwritingScope`

The risks a product can cover. `list_products` gives it with no customer data, so that an agent can drop a product that cannot cover the customer before it asks a question.

`geography` and `insured` are the structured part. A server MUST NOT return an offer for a risk outside the structured part. An agent MUST NOT send answers to `quote` for a product whose structured part excludes the customer. `conditions` holds the rest.

| Field | Type | Required | Description |
| - | - | - | - |
| `geography` | [`Geography`](#geography) | Yes | |
| `insured` | list of [`InsuredType`](#insuredtype) | Yes | What the product insures. At least one. |
| `conditions` | list of string | Yes | The conditions that a machine cannot check, in plain words, for example "Houses built after 1950 only" or "Not for people over 70". Empty when there are none. An agent SHOULD check them against what the customer said before it quotes, and ask the customer when it is not sure. |

### `Geography`

Where the insured person lives, or where the insured good is.

| Field | Type | Required | Description |
| - | - | - | - |
| `countries` | list of [`CountryCode`](#countrycode) | Yes | Countries the product covers. At least one. |
| `subdivisions` | list of [`SubdivisionCode`](#subdivisioncode) | | Subdivisions the product covers, for example US states. Each one MUST belong to a country in `countries`. The product covers the whole of each country that has no subdivision in this list. |

### `InsuredType`

A family of insured, and the kinds of it that a product covers.

| Field | Type | Required | Description |
| - | - | - | - |
| `family` | [`InsuredFamily`](#insuredfamily) | Yes | |
| `kinds` | list of string | | Kinds that the product covers, for example "cat" and "dog". Omit when it covers every kind. |

### `DocumentType`

Kind of document.

Type: one of `pre_contract_information`, `terms_of_business`, `other`, `ipid`, `general_conditions`, `demands_and_needs`.

### `InsuranceDocument`

A document of a product or of an offer. `list_products` gives the documents of each product in [`Product.documents`](#product), and `quote` the documents of each offer in [`Offer.documents`](#offer).

| Field | Type | Required | Description |
| - | - | - | - |
| `type` | [`DocumentType`](#documenttype) | Yes | |
| `title` | string | Yes | |
| `url` | [`Url`](#url) | Yes | |
| `required_before_commitment` | boolean | Yes | True when the law requires that the customer receives this document before they commit, for example the IPID. |

### `ListProductsParams`

Params of `list_products`. Each filter is optional. The server MUST return only the products whose line and underwriting scope match every filter given. With `country`, `subdivision`, `insured_family` and `insured_kind`, the filters cover the whole structured part of the scope, so the agent has only the `conditions` left to check.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | | |
| `subdivision` | [`SubdivisionCode`](#subdivisioncode) | | Products that cover this subdivision. |
| `line` | [`ProductLine`](#productline) | | |
| `insured_family` | [`InsuredFamily`](#insuredfamily) | | Products that insure this family. |
| `insured_kind` | string | | Products that insure this kind of `insured_family`, for example "cat". A product matches when its insured type of that family lists the kind, or lists no kinds. Give it with `insured_family`. |
| `language` | [`LanguageTag`](#languagetag) | | Language of the text in the result: names, summaries, conditions and documents. |
| `cursor` | string | | |

### `ListProductsResult`

| Field | Type | Required | Description |
| - | - | - | - |
| `products` | list of [`Product`](#product) | Yes | |
| `next_cursor` | string | | |

## 5. Quote (level 2)

### `AnswersSchema`

A JSON Schema (2020-12) object that describes the questions of a product. Each property is one question. Each property SHOULD have a `description` in plain words, so that the agent can ask the question.

A question MUST NOT ask for an identity number, a bank account or card number, a tax number, health data of a person or a password. The seller asks for them on its own page: the approval page of `submit_application`, or the `handoff_url` of an offer.

| Field | Type | Required | Description |
| - | - | - | - |
| `type` | `object` | Yes | |
| `properties` | map of map of any | Yes | |
| `required` | list of string | | |

### `Answers`

Answers keyed by property name in `answers_schema`.

Type: map of any.

### `AnswerOrigin`

Who produced the value of an answer.

Type: one of `customer`, `agent`, `third_party`.

### `AnswerSource`

Where one answer comes from. `validated_by_customer` is true when the customer confirmed this value before the agent sent it. It is always true when the customer gave the value. An agent MUST NOT set `validated_by_customer` to true when the customer did not validate that answer.

**`origin: customer`**

| Field | Type | Required | Description |
| - | - | - | - |
| `origin` | `customer` | Yes | |
| `validated_by_customer` | `true` | Yes | |

**`origin: agent`**

| Field | Type | Required | Description |
| - | - | - | - |
| `origin` | `agent` | Yes | |
| `validated_by_customer` | boolean | Yes | |

**`origin: third_party`**

| Field | Type | Required | Description |
| - | - | - | - |
| `origin` | `third_party` | Yes | |
| `validated_by_customer` | boolean | Yes | |
| `source_name` | string | Yes | The third party, by its kind and country, for example "vehicle register (FR)". |

### `AnswerSources`

The source of each answer, keyed like `answers`. An agent MUST give a source for each answer, and no source for a key that has no answer. Otherwise the server returns `answers_invalid`.

Type: map of [`AnswerSource`](#answersource).

### `QuoteParams`

Params of `quote`.

The agent sends the answers that it has, even none. When answers are missing, the server returns `needs_input` with the questions of the product and the missing fields. The agent asks the customer, and calls `quote` again with all the answers. This one loop replaces the tools that give the questions, and the multi-step flow tools (`action`, `stateUpdates`, `sessionId`) that most servers use.

The server keeps the answers and their sources with each offer, until its `valid_until`. `submit_application` takes them from the offer, so the agent does not send them again.

| Field | Type | Required | Description |
| - | - | - | - |
| `product_id` | string | Yes | |
| `answers` | [`Answers`](#answers) | Yes | The answers that the agent has. Empty in a first call that has none. |
| `answer_sources` | [`AnswerSources`](#answersources) | Yes | Where each answer comes from, keyed like `answers`. |
| `options` | list of string | | Options the customer wants priced, by key (optional covers, extra services). |
| `language` | [`LanguageTag`](#languagetag) | | |

### `FieldIssue`

| Field | Type | Required | Description |
| - | - | - | - |
| `field` | string | Yes | |
| `issue` | one of `missing`, `invalid`, `not_accepted` | Yes | |
| `message` | string | | |

### `Offer`

One priced offer. A seller can return several offers: one per tier, per provider, or per duration. Each offer prices one tier of its product. Its price can change after the insurer's checks. The firm price is the one that the approval page shows.

When a server implements `quote`, an agent MUST take the price, the cover, the limits and the excess that it shows the customer from the offer, and MUST NOT take them from a page made for people.

| Field | Type | Required | Description |
| - | - | - | - |
| `offer_id` | string | Yes | |
| `product_id` | string | Yes | |
| `tier` | string | Yes | The `key` of the tier of the product that this offer prices. The cover of its pricing is the cover of that tier for this customer. |
| `provider` | [`ProviderRef`](#providerref) | Yes | |
| `pricing` | [`Pricing`](#pricing) | Yes | The price and the cover. A server SHOULD give `cover.excess`, `cover.limits` and `fees`. An empty `limits` means that the cover has no limit. |
| `valid_until` | [`DateTimeString`](#datetimestring) | Yes | Last moment the customer can apply for the offer. |
| `handoff_url` | [`Url`](#url) | | Page where the customer continues with this exact offer on the seller's site. A server at level 2 MUST give it, because it takes no application. It MUST be on the domain of the seller or of the provider, and MUST NOT contain personal data. |
| `documents` | list of [`InsuranceDocument`](#insurancedocument) | | The documents of this offer. A server SHOULD list every document that the customer must receive before they commit. |

### `QuoteComplete`

A quote with its priced offers, or with the reason why there is none.

| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `complete` | Yes | |
| `offers` | list of [`Offer`](#offer) | Yes | |
| `no_offer` | [`NoOffer`](#nooffer) | | Required when `offers` is empty. |

### `QuoteNeedsInput`

The questions of the product, and the answers that are still missing or wrong.

| Field | Type | Required | Description |
| - | - | - | - |
| `status` | `needs_input` | Yes | |
| `answers_schema` | [`AnswersSchema`](#answersschema) | Yes | The questions of the product. The agent asks the missing ones from it. |
| `missing_fields` | list of [`FieldIssue`](#fieldissue) | Yes | Properties of `answers_schema` that are missing, not valid or not accepted. |

### `QuoteResult`

Type: [`QuoteComplete`](#quotecomplete) or [`QuoteNeedsInput`](#quoteneedsinput).

### `NoOffer`

Why no offer is possible.

| Field | Type | Required | Description |
| - | - | - | - |
| `reason_code` | [`NoOfferReason`](#noofferreason) | Yes | |
| `message` | string | Yes | Plain-language explanation the agent can pass to the customer. |

### `NoOfferReason`

Stable reason why no offer is possible. Servers SHOULD use a value of [`KnownNoOfferReason`](#knownnoofferreason). Other values MUST be lower case with underscores.

Type: string. Pattern: `^[a-z][a-z0-9_]*$`.

### `KnownNoOfferReason`

Common reason codes. `outside_underwriting_scope` means that the risk is outside the product's underwriting scope: its geography, its insured types or its conditions. A quote for a risk outside the structured part MUST get this reason.

Type: one of `outside_underwriting_scope`, `risk_not_accepted`, `age_not_accepted`, `breed_not_accepted`, `claims_history_not_accepted`.

## 6. Premium and cover

### `PremiumPeriod`

Type: one of `month`, `quarter`, `half_year`, `year`, `single`.

### `Premium`

| Field | Type | Required | Description |
| - | - | - | - |
| `amount` | [`Money`](#money) | Yes | |
| `period` | [`PremiumPeriod`](#premiumperiod) | Yes | |
| `taxes_included` | boolean | Yes | True when taxes and mandatory levies are in `amount`. |

### `CoverLimit`

| Field | Type | Required | Description |
| - | - | - | - |
| `key` | string | Yes | Stable key, for example "vet\_costs\_per\_year". |
| `label` | string | Yes | |
| `limit` | [`Money`](#money) | | |
| `reimbursement_rate` | number | | Share of a claim paid back, from 0 to 1. Used by pet and health cover. |

### `ExcessBasis`

What one excess applies to.

Type: one of `per_claim`, `per_year`, `per_condition`.

### `CoverSummary`

| Field | Type | Required | Description |
| - | - | - | - |
| `included` | list of string | Yes | Covers included, as short labels. |
| `limits` | list of [`CoverLimit`](#coverlimit) | | |
| `excess` | [`Money`](#money) | | |
| `excess_basis` | [`ExcessBasis`](#excessbasis) | | What the excess applies to. Required when `excess` is above zero. |
| `main_exclusions` | list of string | | Main exclusions. The full list is in the documents. |
| `waiting_periods` | list of [`WaitingPeriod`](#waitingperiod) | | The waiting period of each cover. Each `applies_to` MUST be a label of `included`. Give 0 days for a cover that starts at once, so that the wait of an illness does not read as the wait of an accident. |

### `WaitingPeriod`

The days after the start date before a claim for one cover is paid.

| Field | Type | Required | Description |
| - | - | - | - |
| `applies_to` | string | Yes | The cover it applies to: a label of `included`, for example "Illness". |
| `days` | number | Yes | Days after the start date. 0 when the cover starts at once. |

### `Fee`

A fee that the customer pays on top of the premium, for example a policy fee or a broker fee.

| Field | Type | Required | Description |
| - | - | - | - |
| `key` | string | Yes | Stable key, for example "policy\_fee". |
| `label` | string | Yes | |
| `amount` | [`Money`](#money) | Yes | |
| `period` | [`PremiumPeriod`](#premiumperiod) | Yes | How often the customer pays it. `single` for a fee paid once. |

### `ProductOption`

An option the customer can add (optional cover, extra service).

| Field | Type | Required | Description |
| - | - | - | - |
| `key` | string | Yes | |
| `label` | string | Yes | |
| `price` | [`Premium`](#premium) or [`Money`](#money) | | Cost of the option, in the same form as the main price. |

### `Pricing`

The price of an offer, and the cover it buys.

| Field | Type | Required | Description |
| - | - | - | - |
| `premium` | [`Premium`](#premium) | Yes | |
| `fees` | list of [`Fee`](#fee) | | Fees on top of the premium. An empty list means that the customer pays no fee. |
| `cover` | [`CoverSummary`](#coversummary) | Yes | |
| `options` | list of [`ProductOption`](#productoption) | | The options in this price, from the `options` of the quote. |

## 7. Applications (level 3)

### `PartyRole`

Role of a party in the application.

Type: one of `subscriber`, `payer`, `insured`, `beneficiary`.

### `Party`

A person or organisation in the application. Data in a party MUST be limited to what the product needs. Identity numbers MUST NOT be here.

| Field | Type | Required | Description |
| - | - | - | - |
| `party_ref` | string | Yes | Local reference, unique in one application. |
| `kind` | one of `person`, `organisation` | Yes | |
| `roles` | list of [`PartyRole`](#partyrole) | Yes | |
| `display_name` | string | Yes | |
| `relationship_to_subscriber` | string | | Relationship to the subscriber, for example "self", "spouse", "child", "employee". |
| `date_of_birth` | [`DateString`](#datestring) | | |
| `country_of_residence` | [`CountryCode`](#countrycode) | | |

### `SubmitApplicationParams`

Params of `submit_application`. The offer comes from a complete quote. The server takes the answers, their sources and the options from that quote, so the agent does not send them again. When the customer wants to change an answer, the agent calls `quote` again, and applies for an offer of the new quote.

| Field | Type | Required | Description |
| - | - | - | - |
| `offer_id` | string | Yes | |
| `parties` | list of [`Party`](#party) | Yes | |
| `language` | [`LanguageTag`](#languagetag) | | Language of the `summary` and of the approval page. |

### `SubmitApplicationResult`

An application that waits for the customer. `submit_application` commits nothing. The customer approves the application on the seller's page at `url`, then signs and pays on the same site. When the client declares MCP URL-mode elicitation, the server SHOULD open the page with a URL-mode elicitation of `url`. Otherwise the agent gives the customer `url`.

The seller MUST keep what the customer approved, with the answers and their sources, the price and the documents, for the period that the law requires.

| Field | Type | Required | Description |
| - | - | - | - |
| `application_id` | string | Yes | |
| `application_key` | [`ApplicationKey`](#applicationkey) | Yes | The key to read the application with `get_operation`. See [`ApplicationKey`](#applicationkey). |
| `summary` | string | Yes | The application in plain words, so that the customer can decide from it alone: the product, the tier, the insurer and the price. It MUST give each answer and its source, and MUST ask the customer to approve only when each answer is true and complete, so that the approval is also the customer's confirmation of the answers. |
| `url` | [`Url`](#url) | Yes | The seller's page where the customer approves the application, then signs and pays. Before the customer can approve, the page MUST show the firm price, each answer with its source, and a link to each document of the product and of the offer with `required_before_commitment: true`. It MUST let the customer approve or refuse. The page MUST take an approval only from a form that the person submits on it, never from a GET request, so that a link preview cannot approve. The URL MUST be on the domain of the seller, MUST hold a token of at least 128 bits of randomness that is neither the `application_id` nor the `application_key`, and MUST NOT contain personal data. |
| `expires_at` | [`DateTimeString`](#datetimestring) | Yes | Last moment the customer can approve. After it, the application is `expired`. |

### `ApplicationKey`

The key to read an application with `get_operation`. The server returns it only in the result of `submit_application`. It MUST hold at least 128 bits of randomness. It is not in the approval page, so the agent keeps it to itself.

Type: string.

### `ApplicationState`

Where an application is.

Type: one of `waiting`, `approved`, `refused`, `expired`.

### `GetOperationParams`

Params of `get_operation`.

| Field | Type | Required | Description |
| - | - | - | - |
| `application_id` | string | Yes | |
| `application_key` | [`ApplicationKey`](#applicationkey) | Yes | |

### `GetOperationResult`

Result of `get_operation`. When the `application_key` is not the key of the application, the server returns `application_not_found`.

| Field | Type | Required | Description |
| - | - | - | - |
| `application_id` | string | Yes | |
| `state` | [`ApplicationState`](#applicationstate) | Yes | |

## 8. Errors

### `AipErrorCode`

Type: one of `invalid_params`, `rate_limited`, `unavailable`, `not_supported`, `not_licensed`, `product_not_found`, `answers_invalid`, `offer_not_found`, `offer_expired`, `application_not_found`.

### `AipError`

Error returned in an MCP tool result with `isError: true`, in `structuredContent.error`, with the same JSON as text in `content`.

| Field | Type | Required | Description |
| - | - | - | - |
| `code` | [`AipErrorCode`](#aiperrorcode) | Yes | |
| `message` | string | Yes | |
| `fields` | list of [`FieldIssue`](#fieldissue) | | |
| `retryable` | boolean | Yes | True when the same call can succeed later with no change, as for `rate_limited` and `unavailable`. |
| `retry_after_seconds` | number | | When the agent SHOULD retry, when `retryable` is true. |

## 9. Tool index

### `ToolName`

Type: one of `get_distributor`, `list_products`, `quote`, `submit_application`, `get_operation`.

### `ToolSignatures`

Params and result type of each tool.

| Field | Type | Required | Description |
| - | - | - | - |
| `get_distributor` | object with `params`, `result` | Yes | |
| `list_products` | object with `params`, `result` | Yes | |
| `quote` | object with `params`, `result` | Yes | |
| `submit_application` | object with `params`, `result` | Yes | |
| `get_operation` | object with `params`, `result` | Yes | |

## R1. Common types

### `DomainName`

Host name, lower case, with no scheme, port or path, for example "pets.example.com".

Type: string. Pattern: `^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$`.

### `RegisterIdentifier`

An entry in a public register.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | Country of the register. |
| `identifier_type` | [`RegisterIdentifierType`](#registeridentifiertype) | Yes | |
| `identifier` | string | Yes | |
| `register` | string | | Name of the register. Give it when `identifier_type` is "other". |

### `SourceAccess`

How the registry reads a public register.

Type: one of `api`, `bulk_file`, `web_page`.

### `RegisterSource`

A public register that the registry reads.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | |
| `subdivisions` | list of [`SubdivisionCode`](#subdivisioncode) | | Subdivisions that this source covers. Omit when it covers the whole country. |
| `register` | string | Yes | Name of the register, for example "ORIAS". |
| `regulator` | string | Yes | |
| `covers` | list of one of `intermediaries`, `insurers` | Yes | |
| `identifier_type` | [`RegisterIdentifierType`](#registeridentifiertype) | Yes | |
| `access` | [`SourceAccess`](#sourceaccess) | Yes | |
| `url` | [`Url`](#url) | Yes | Public home page of the register. |

## R2. Licence check

### `VerifyLicenceParams`

Params of `verify_licence`. They name a company and a market, never a person.

| Field | Type | Required | Description |
| - | - | - | - |
| `capacity` | one of `distributor`, `provider` | Yes | "distributor" for a seller, "provider" for the party that carries the risk, for example the insurer in [`Offer.provider`](#offer). |
| `subject` | object with `domain`, `identifier`, `legal_name` | Yes | |
| `country` | [`CountryCode`](#countrycode) | Yes | Country where the customer buys. |
| `subdivision` | [`SubdivisionCode`](#subdivisioncode) | | Subdivision where the customer buys. REQUIRED in the United States. |
| `line` | [`ProductLine`](#productline) | | |

### `LicenceStatus`

Status of one register entry, as the registry reads it.

Type: one of `active`, `pending`, `lapsed`, `suspended`, `revoked`, `not_found`, `name_mismatch`.

### `LicenceCheck`

The result of reading one entry in one public register.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | |
| `regulator` | string | Yes | |
| `register` | string | Yes | |
| `identifier_type` | [`RegisterIdentifierType`](#registeridentifiertype) | Yes | |
| `identifier` | string | Yes | |
| `role` | [`DistributorRole`](#distributorrole) | | Role that the entry gives. Omit when the status is "not\_found". |
| `status` | [`LicenceStatus`](#licencestatus) | Yes | |
| `register_status` | string | | The status in the words of the register, for example "Inscrit". |
| `categories` | list of string | | Register categories, for example ORIAS "COA". |
| `lines` | list of [`ProductLine`](#productline) | | Lines that the categories cover. Omit when they cover every line. |
| `subdivisions` | list of [`SubdivisionCode`](#subdivisioncode) | | Subdivisions where the entry applies. Omit when it covers the whole country. |
| `passports` | list of [`CountryCode`](#countrycode) | | Other countries where the entry may operate (EU and EEA). |
| `name_in_register` | string | | |
| `valid_until` | [`DateString`](#datestring) | | |
| `access` | [`SourceAccess`](#sourceaccess) | Yes | |
| `source_date` | [`DateString`](#datestring) | | Date of the data in the source, when it is older than the read. |
| `checked_at` | [`DateTimeString`](#datetimestring) | Yes | When the registry read this entry. |
| `source_url` | [`Url`](#url) | Yes | Public page where anyone can check the entry. |

### `DomainLink`

How the registry tied the domain to the entries. Only "register" and "confirmed" support "licensed".

Type: one of `register`, `confirmed`, `claimed`, `not_linked`.

### `NotLicensedReason`

Type: one of `no_entry`, `licence_not_active`, `name_mismatch`, `role_not_covered`, `subdivision_not_covered`, `line_not_covered`.

### `UnknownReason`

Type: one of `country_not_covered`, `subdivision_required`, `register_unavailable`, `subject_not_identified`, `domain_not_linked`.

### `LicenceVerdict`

**`verdict: licensed`**

| Field | Type | Required | Description |
| - | - | - | - |
| `verdict` | `licensed` | Yes | |
| `message` | string | Yes | Plain-language explanation that the AI agent can pass to the customer. |

**`verdict: not_licensed`**

| Field | Type | Required | Description |
| - | - | - | - |
| `verdict` | `not_licensed` | Yes | |
| `reason` | [`NotLicensedReason`](#notlicensedreason) | Yes | |
| `message` | string | Yes | Plain-language explanation that the AI agent can pass to the customer. |

**`verdict: unknown`**

| Field | Type | Required | Description |
| - | - | - | - |
| `verdict` | `unknown` | Yes | |
| `reason` | [`UnknownReason`](#unknownreason) | Yes | |
| `message` | string | Yes | Plain-language explanation that the AI agent can pass to the customer. |

### `VerifyLicenceResult`

Result of `verify_licence`. Keep it with the record of the sale.

| Field | Type | Required | Description |
| - | - | - | - |
| `check_id` | string | Yes | |
| `params` | [`VerifyLicenceParams`](#verifylicenceparams) | Yes | The params of the call, so that the result is a complete record alone. |
| `subject` | object with `legal_name`, `lei`, `domain`, `domain_link`, `listed`, `mcp_url` | Yes | |
| `licences` | list of [`LicenceCheck`](#licencecheck) | Yes | Every entry the registry read for the party. |
| `outcome` | [`LicenceVerdict`](#licenceverdict) | Yes | |
| `checked_at` | [`DateTimeString`](#datetimestring) | Yes | |

## R3. Search

### `ListedDistributor`

A server that the registry lists.

| Field | Type | Required | Description |
| - | - | - | - |
| `legal_name` | string | Yes | |
| `trading_name` | string | | |
| `lei` | [`Lei`](#lei) | | |
| `domain` | [`DomainName`](#domainname) | Yes | |
| `mcp_url` | [`Url`](#url) | Yes | MCP endpoint of the server. |
| `roles` | list of [`DistributorRole`](#distributorrole) | Yes | |
| `conformance_level` | [`ConformanceLevel`](#conformancelevel) | Yes | |
| `lines` | list of [`ProductLine`](#productline) | Yes | |
| `countries` | list of [`CountryCode`](#countrycode) | Yes | |
| `subdivisions` | list of [`SubdivisionCode`](#subdivisioncode) | | Subdivisions where the server holds a licence. Omit when its licence covers the whole country. |
| `insured_families` | list of [`InsuredFamily`](#insuredfamily) | | |
| `complaints_url` | [`Url`](#url) | | |
| `licence_check` | [`VerifyLicenceResult`](#verifylicenceresult) | Yes | The licence check of the server for the market of the search. Its verdict is "licensed". |
| `listed_since` | [`DateString`](#datestring) | Yes | |

### `SearchDistributorsParams`

Params of `search_distributors`. They describe a market, never a person.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | Country where the customer buys. |
| `subdivision` | [`SubdivisionCode`](#subdivisioncode) | | Subdivision where the customer buys, for example a US state. |
| `line` | [`ProductLine`](#productline) | | |
| `insured_family` | [`InsuredFamily`](#insuredfamily) | | |
| `min_conformance_level` | [`ConformanceLevel`](#conformancelevel) | | Return only servers of this level or above. |
| `cursor` | string | | |

### `SearchDistributorsResult`

Result of `search_distributors`. The order carries no meaning: never show it as a ranking.

| Field | Type | Required | Description |
| - | - | - | - |
| `distributors` | list of [`ListedDistributor`](#listeddistributor) | Yes | |
| `next_cursor` | string | | |

## R4. Country rules

### `GetCountryRulesParams`

Params of `get_country_rules`.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | |
| `subdivision` | [`SubdivisionCode`](#subdivisioncode) | | Adds the file of this subdivision, when one exists. |
| `line` | [`ProductLine`](#productline) | | Adds the file of this line, when one exists. |

### `RulesFile`

One rules file of the AIP skill: Markdown with a YAML front matter that gives the same values as these fields.

| Field | Type | Required | Description |
| - | - | - | - |
| `country` | [`CountryCode`](#countrycode) | Yes | |
| `subdivision` | [`SubdivisionCode`](#subdivisioncode) | | |
| `line` | [`ProductLine`](#productline) | | |
| `version` | string | Yes | |
| `owner` | string | Yes | |
| `status` | one of `draft`, `endorsed` | Yes | |
| `endorsed_by` | string | | |
| `reviewed_at` | [`DateString`](#datestring) | | |
| `effective_from` | [`DateString`](#datestring) | Yes | |
| `language` | [`LanguageTag`](#languagetag) | Yes | |
| `content` | string | Yes | The whole file, unchanged, front matter included. |
| `url` | [`Url`](#url) | Yes | Public HTTPS address of the same file. |
| `skill_uri` | string | | URI of the same file in the AIP skill. |

### `GetCountryRulesResult`

Result of `get_country_rules`: the file of the country first. Follow every file.

| Field | Type | Required | Description |
| - | - | - | - |
| `files` | list of [`RulesFile`](#rulesfile) | Yes | |

## R5. Errors

### `RegistryErrorCode`

Type: one of `country_not_covered`.

### `RegistryError`

Error of a registry tool, in `structuredContent.error` of a result with `isError: true`.

| Field | Type | Required | Description |
| - | - | - | - |
| `code` | [`RegistryErrorCode`](#registryerrorcode) | Yes | |
| `message` | string | Yes | |

## R6. Registry server

### `RegistrySettings`

Settings of the registry extension, in its MCP `server/discover` response.

| Field | Type | Required | Description |
| - | - | - | - |
| `version` | string | Yes | |
| `countries` | list of [`CountryCode`](#countrycode) | Yes | Countries where the registry checks licences and lists servers. |
| `rules_countries` | list of [`CountryCode`](#countrycode) | Yes | Countries that have a rules file. |
| `sources` | list of [`RegisterSource`](#registersource) | Yes | |
| `policy_url` | [`Url`](#url) | Yes | Page where the operator publishes how it lists servers and checks licences. |
| `listing_url` | [`Url`](#url) | Yes | Page where a distributor asks to be listed. |


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