# v1.3.0 — contract fixes

Idempotency keys accept any string, `country` becomes optional, and webhook URLs must be HTTPS.

Jun 10, 2026 · Breaking

Contract-correctness wave from an API test pass. Idempotency keys no longer have to be UUIDs, address country becomes optional, webhook endpoints must be HTTPS, and several error responses are now more accurate (correct codes, correct status, and a previously-opaque 500 turned into an actionable 422).

## What breaks

- **Webhook endpoints must be HTTPS** — `POST /v1/webhooks` (and updates) now reject `http://` URLs with 422 `WEBHOOK_URL_MUST_BE_HTTPS`. Signed fiscal payloads are never delivered in cleartext. Re-register any non-HTTPS endpoint over HTTPS.
- **Customers can't carry both `nif` and `alternative_id`** — sending both on `POST /v1/customers` now returns 422 `ALTERNATIVE_ID_AND_NIF_EXCLUSIVE`. Previously the alternative_id was silently dropped and only the NIF kept. Send exactly one identifier.
- **`POST /v1/companies` status changed 404 → 403** — clients branching on 404 `COMPANY_NOT_FOUND` for the multi-NIF-unavailable case must switch to 403 `MULTI_NIF_NOT_ENABLED`.

## What else changed

- **`Idempotency-Key` accepts any unique string** — not just a UUID. Any client-generated key matching `^[a-zA-Z0-9_-]{1,255}$` works (e.g. `invoice-order-12345`). UUIDs still work but are no longer required. Previously a non-UUID key was rejected with 422.
- **`address.country` is now optional** — `country_code` (ISO 3166-1 alpha-2) is the canonical field. If you omit `country` it defaults to the country name; you only need to send `country_code`.
- **`X-Request-Id` response header** — every response now carries `X-Request-Id`, matching `meta.request_id` in the body, so you can correlate logs without parsing the payload.
- **`POST /v1/companies` returns a clear 403** — when multi-NIF isn't available on your plan it now responds 403 `MULTI_NIF_NOT_ENABLED` instead of a misleading 404 `COMPANY_NOT_FOUND` on a creation endpoint.
- **Series with an unknown format variable now fails cleanly** — `POST /v1/configuration/series` with an unrecognized `{VARIABLE}` returns 422 `SERIES_FORMAT_UNRECOGNIZED_VARS` with the standard error envelope, instead of an opaque empty 500.
- **Consistent error code for alternative IDs** — the wire error code is now `ALTERNATIVE_ID_INVALID` (matching the published catalog), not an internal Spanish variant.

## Endpoints

- `POST /v1/companies` — Returns 403 MULTI_NIF_NOT_ENABLED (was 404) when multi-NIF is not available on the plan

## Where to go next

- [Idempotency guide](/guides/idempotency)
- [Error reference](/errors)

---

Full OpenAPI spec: https://docs.beel.es/api/openapi