> For the complete documentation index, see [llms.txt](https://chekin.gitbook.io/chekin-public-api/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://chekin.gitbook.io/chekin-public-api/api-reference/guests/guest-schema.md).

# Guest Schema

The "Guest Schema" endpoint tells you **which guest fields you must collect for a given reservation, and how to render and validate them**. The answer is not static: it depends on the country of the housing, on the Police/Stats connection of that housing, and on what the guest has already answered (nationality, document type, birth date, residence country…).

Because of that, the schema is not something you fetch once and cache. It is a **conversation**: every time the guest fills in a field that can influence the rest of the form, you send the current state of the form back to the schema endpoint and re-render with the fields it returns.

{% hint style="info" %}
This endpoint returns the mandatory **default** fields. If the housing uses a Custom form configured in the dashboard, or you want the whole form with groups and translations, use [Guest Schema v2](/chekin-public-api/api-reference/guests/guest-schema-v2.md) instead. Both versions are supported.
{% endhint %}

{% hint style="warning" %}
Requesting the schema only once — for example, only with `nationality` — is not enough. Conditional mandatory fields such as `document_support_number`, `residence_province` or `purpose_of_stay` only appear once the values they depend on are sent, so a guest submitted without them is created but can later be **rejected by the Police service**. Re-request the schema whenever the guest changes one of the fields accepted in the request body (see the reference block at the bottom of the page).
{% endhint %}

## Endpoint

```
POST {{env}}/guests/schema/
```

## Request and response in short

The request body is the **current state of your form**: `reservation_id` is the only mandatory field, every other field is a value the guest has already provided. Send all the ones you have, on every call.

The response has two keys:

* **default** — the fields you must collect. Through the public API it contains **only the fields that are mandatory** for the current state of the form; if a field is not in the array, you don't need it (yet). Each entry tells you how to render it (`type`, `subtype`, `options` / `options_url`), what to call it (`name` is the key for [Create Guest](/chekin-public-api/api-reference/guests/create-guest.md)) and how to validate it (`format`)
* **iv** — the Identity Verification settings of the reservation, or `null` when the housing has no self online check-in enabled

The full list of request fields and response attributes is in the reference block at the bottom of this page.

## Worked example

A reservation in a Spanish housing connected to the Police service (SES Hospedajes).

{% tabs %}
{% tab title="1. First call" %}
You only know the reservation. Ask what the form needs.

```javascript
POST {{env}}/guests/schema/
Authorization: JWT <token>
Content-Type: application/json

{
  "reservation_id": "fd73497a14cc4c0da9951b9824321169"
}
```

The response contains the base mandatory fields — `name`, `surname`, `second_surname`, `birth_date`, `nationality`, `document_type`, `document_number`, `residence_country`, `phone`, `email`, `signature`…

Note that `document_support_number` is **not** there yet: Chekin cannot know whether it applies until it knows the document type.
{% endtab %}

{% tab title="2. After nationality" %}
The guest picks Spain. Send it back, together with everything else already filled in.

```javascript
POST {{env}}/guests/schema/
Authorization: JWT <token>
Content-Type: application/json

{
  "reservation_id": "fd73497a14cc4c0da9951b9824321169",
  "nationality": "ES",
  "birth_date": "1990-04-12"
}
```

The `options` of the `document_type` field are now the documents a Spanish national may use, and the residence fields gained Spanish provinces in their `options_url`.
{% endtab %}

{% tab title="3. After document type" %}
The guest selects the Spanish national identity card, DNI (`ES_D`).

```javascript
POST {{env}}/guests/schema/
Authorization: JWT <token>
Content-Type: application/json

{
  "reservation_id": "fd73497a14cc4c0da9951b9824321169",
  "nationality": "ES",
  "birth_date": "1990-04-12",
  "document_type": "ES_D",
  "residence_country": "ES"
}
```

Now the response includes a new mandatory field:

```json
{
  "type": "Text",
  "subtype": null,
  "name": "document_support_number",
  "label": "Document support number",
  "placeholder": "Support number",
  "required": true,
  "format": "^[a-zA-Z]{3}\\d{6}$",
  "is_leaders_field": false,
  "country_field": false
}
```

…and `residence_province` appeared with an `options_url` restricted to Spain. Render the two new inputs, and when the guest picks the province, call the schema again so the municipality/city options can be resolved. The value to send is the province **code** (`ES-M`), not its name. See [Location fields](/chekin-public-api/api-reference/guests/location-and-document-fields.md).

The support number is also required for `ES_N` (NIE/TIE), and neither document type needs it for guests under 14.
{% endtab %}

{% tab title="4. Submit" %}
Once the schema returns no field you haven't collected, create the guest with the field `name`s as keys.

```javascript
POST {{env}}/guests/
Authorization: JWT <token>
Content-Type: application/json

{
  "reservation_id": "fd73497a14cc4c0da9951b9824321169",
  "name": "Olga",
  "surname": "Fernandez",
  "second_surname": "Ruiz",
  "birth_date": "1990-04-12",
  "nationality": "ES",
  "document_type": "ES_D",
  "document_number": "12345678Z",
  "document_support_number": "ABC123456",
  "residence_country": "ES",
  "residence_province": "ES-M",
  "residence_city": "Madrid",
  "residence_municipality": "28079",
  "...": "..."
}
```

{% endtab %}
{% endtabs %}

## Rules of thumb

* **Re-request the schema on every field that the request body accepts.** Fields such as `name` or `email` never change the form, so they don't need a new call — but `nationality`, `citizenship`, `document_type`, `document_expedition_country`, `birth_date`, `residence_country`, `residence_province`, `arrived_from_country`, `arrived_from_district`, `birth_place_country`, `next_destination_country`, `purpose_of_stay`, `phone`, `is_leader`, `invoice_leader_type` and `recipient_code_type` all do
* **Always send the full known state**, not only the field that changed. Conditions combine several values at once — for instance the Spanish support number depends on `document_type` *and* on the guest not being a minor, which is derived from `birth_date`
* **Never hardcode a country's field list.** The requirements change when a housing is connected to a Police or Stats service, and the schema is the only source of truth
* **Connect the housing to the Police service before the guests register.** Guests who complete the form while the housing was not yet connected were validated against a lighter schema, so their profiles may be missing data and will need to be completed before they can be sent
* **Send codes, not labels, for `Select` fields.** For location fields, send the name in `*_city` and the code in `*_municipality`. See [Location fields](/chekin-public-api/api-reference/guests/location-and-document-fields.md)
* **Use `format` to validate on your side**, so the guest fixes the value while they are still in the form instead of failing at submission
* Empty strings and placeholder characters (a single `.`, a dash) are accepted as text but are rejected by the Police services. Validate that mandatory fields carry real values

{% openapi src="/files/2YNWdcD7SWYAbJN2lC4R" path="/guests/schema" method="post" %}
[Chekin-Chekin-1.0.0-resolved.json](https://3564732132-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfAJzL2tAGO9ZwOToBa0R%2Fuploads%2Fgit-blob-0641a0e07e27281f11fe82de446c7229bfe15c1e%2FChekin-Chekin-1.0.0-resolved.json?alt=media)
{% endopenapi %}

<details>

<summary>Validation of the request values</summary>

* Country fields (`nationality`, `citizenship`, `residence_country`, `birth_place_country`, `arrived_from_country`, `next_destination_country`, `document_expedition_country`) must be **ISO 3166-1 alpha-2** codes, uppercase — `ES`, not `ESP` or `Spain`
* `birth_date` must be `YYYY-MM-DD`
* `document_type` must be one of the values returned in the `options` of the `document_type` field of a previous schema response

An invalid value returns `400` instead of a schema, so re-requesting the schema also works as an early validation of what the guest typed.

</details>
