SES Hospedajes

Tracking the traveller report filed with Spain’s Ministry of the Interior (RD 933/2021).

How the report is filed

There is nothing to call: on the night of arrival (23:30 mainland Spain time), Kinapi automatically files with SES Hospedajes the registered guests of every check-in arriving that day. If part of the party is missing at that hour, a partial report goes out with whoever is there. Whatever comes in later — a guest who registers after that hour or the next day, the stragglers of a party — does not wait for another night: it is filed as a delta in the next hourly run. Each guest is an independent communication in SES, so extending the party never duplicates anything.

SES processes batches asynchronously: after filing, we poll for the result and store each guest’s communication code (or the errors the Ministry returned).

Read the report status

GET/checkins/{reservationId}/ses
curl
curl https://api.kinapi.es/api/v1/checkins/R-2026-0412/ses \
  -H "ocp-apim-subscription-key: YOUR_API_KEY"
200 OK
{
  "status": "confirmed",
  "results": [
    {
      "lote": "20260815-000123",
      "env": "prod",
      "status": "polled_ok",
      "codigoEstablecimiento": "0000012345",
      "sentAt": "2026-08-14T21:30:05.000Z",
      "polledAt": "2026-08-14T22:30:10.000Z",
      "annulment": null,
      "comunicaciones": [
        {
          "guestId": "5f0c33f1-…",
          "guestName": "María García López",
          "codigoComunicacion": "SES-2026-…",
          "errores": [],
          "rechazos": []
        }
      ]
    }
  ]
}
Statuses of a submission (results[].status)
FieldTypeDescription
sentstatusBatch sent, waiting for SES to process it.
polled_okstatusSES confirmed every communication in the batch.
polled_errorstatusSES rejected one of the communications — see the per-guest errors.
http_errorstatusThe submission never reached SES (network or credential problem). It is retried.

A check-in can have several submissions (partials + deltas). The aggregate status that matters is the check-in’s own status: confirmed means every guest has a communication code.

Annulments

When a filed booking is cancelled, or its dates change and it is filed again, Kinapi annuls its communications with the Ministry. Each submission carries in annulment where that annulment stands; null if it was never annulled.

results[].annulment
{
  "status": "confirmed",
  "reason": "cancelled",
  "lote": "20260816-000045",
  "requestedAt": "2026-08-16T10:12:00.000Z",
  "checkedAt": "2026-08-16T11:30:08.000Z",
  "attempts": 0,
  "error": null
}
annulment fields
FieldTypeDescription
statusstringWhere it stands (table below).
reasonstringcancelled, the booking was cancelled; dates_changed, its dates changed and it was filed again.
lotestring | nullBatch number of the annulment request; null while the Ministry has not accepted it.
requestedAtISO 8601 | nullWhen the Ministry accepted the request.
checkedAtISO 8601 | nullWhen the result of its processing was read.
attemptsintegerFailed attempts so far.
errorstring | nullWhy it was rejected, verbatim from the Ministry.
Annulment statuses (annulment.status)
FieldTypeDescription
retryingstatusThe Ministry did not accept the request; Kinapi retries it every hour.
abandonedstatusIt was retried for three days (72 attempts) without success. It needs a manual check in SES.HOSPEDAJES; ses.cancel_failed was emitted.
requestedstatusThe Ministry accepted the request and has not processed it yet. It is checked every hour.
confirmedstatusProcessed: the communications no longer stand.
rejectedstatusProcessed and rejected: the communications STILL stand (error says why). ses.cancel_failed was emitted.

Proof of filing

GET/checkins/{reservationId}/ses/justificante

The Ministry issues no PDF for filings made through the web service: the official record of each one is its communication code. If an inspection asks you to prove that you filed a stay, this PDF (the «justificante de comunicación») gathers those codes in a document you can show.

It carries the establishment (name, establishment code, address, landlord, tax number and SES landlord code), the stay and, for every submission, its batch number, destination, date and result, each guest’s communication code and the annulment with its result, if there was one. It is generated on request, so it always reflects the current state; if the booking has no real submission to the Ministry, the document says so at the top. It is in Spanish, like the filing itself.

curl
curl -OJ https://api.kinapi.es/api/v1/checkins/R-2026-0412/ses/justificante \
  -H "ocp-apim-subscription-key: YOUR_API_KEY"

You can also download it from the booking page in the panel, and it is included in every export.

Ministry errors

When SES rejects a communication (invalid document, wrong municipality…), the exact error is left in comunicaciones[].errores and the check-in moves to error with the detail in errorReason. Once the data is corrected, the next nightly run retries it automatically.

The Ministry’s wording is not meant to be read: it arrives with its prefix repeated and never says what to fix. Alongside it you get comunicaciones[].rechazos, the same response already classified so you can act on it without parsing strings. It carries no translated text — the language is your system’s call.

A classified rejection
{
  "errores": [
    "Error validación de datos Error de validación en la comunicación [4]: [Valor incorrecto para el campo NIF .  NIF: [53572037 T].]"
  ],
  "rechazos": [
    { "codigo": "campoInvalido", "campo": "numeroDocumento", "valor": "53572037 T", "comunicacion": 4 }
  ]
}
Rejection codes (rechazos[].codigo)
CampoTipoDescripción
campoInvalidorejectionThe Ministry rejected a field’s value; which one is in `campo`.
codigoPostalInvalidorejectionThe postcode does not exist in Spain.
documentoDuplicadorejectionThe same document number appears twice under the same role.
numPersonasNoCoinciderejectionThe report declared a different number of travellers than it carried.

These codes come from real rejections collected in production, not from a theoretical list. A rejection Kinapi cannot yet classify does not appear in rechazos: it stays whole in errores, which is never trimmed.

File the report now

POST/checkins/{reservationId}/ses

Forces the submission without waiting for the nightly sweep. It returns the batch number assigned; SES does not confirm on the spot, so each guest’s communication code will still arrive on the hourly poll (read it with the GET above). In test mode the result is there at once: a simulator answers, with env: "test" on the submission.

It answers 409 not_ready if the conditions are not met yet — no guests, no signature where one is required, or a property with no establishment code — with the concrete reason in details.

curl
curl -X POST https://api.kinapi.es/api/v1/checkins/R-2026-0412/ses \
  -H "ocp-apim-subscription-key: YOUR_API_KEY"

Official code tables

GET/ses/catalogs
POST/ses/catalogs

The values SES accepts today for document type, sex, relationship and payment type. Read them to build your dropdowns instead of hard-coding the codes; the POST refreshes them against the Ministry.