InvoiceUpdatePreconditions
Optional preconditions for PUT and PATCH /v1/invoices/{id}. Rejected on POST /v1/invoices. Evaluated inside the update transaction against the live document, before any write or numbering side effect. They are never persisted and never returned. Omitting both leaves behaviour unchanged.
Properties
| Name | Type | Description |
|---|---|---|
| ifStatus | string | Expected current status. A mismatch returns 409 INVOICE_STATUS_PRECONDITION_FAILED. With `draft` it also fails when the invoice already carries issuance evidence. The list is closed: a VeriFactu hash, |
| ifUpdatedAt | string | The `updatedAt` value of the invoice, as returned by a previous GET. It is an exact string comparison, not a date comparison (surrounding whitespace is trimmed first): an equivalent instant in another |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/frihet-io/json-schema/frihet-io-invoice-update-preconditions-schema.json",
"title": "InvoiceUpdatePreconditions",
"description": "Optional preconditions for PUT and PATCH /v1/invoices/{id}. Rejected on\nPOST /v1/invoices. Evaluated inside the update transaction against the live\ndocument, before any write or numbering side effect. They are never persisted\nand never returned. Omitting both leaves behaviour unchanged.\n",
"x-generated": "2026-11-09",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/frihet-io-openapi.json#/components/schemas/InvoiceUpdatePreconditions",
"type": "object",
"properties": {
"ifStatus": {
"type": "string",
"enum": [
"draft",
"sent",
"partial",
"paid",
"overdue",
"cancelled"
],
"writeOnly": true,
"description": "Expected current status. A mismatch returns 409\nINVOICE_STATUS_PRECONDITION_FAILED. With `draft` it also fails when the\ninvoice already carries issuance evidence. The list is closed: a VeriFactu\nhash, rectificativa numbering authority, sentAt, or any of faceStatus,\nfaceNumeroRegistro, faceSubmittedAt, tbaiStatus, tbaiCsv. Anything else is not\nchecked; in particular `eInvoice.sdiSubmission` (Italian SDI) and `ksefStatus`\nand related fields (Polish KSeF) do not block, so a draft with only those\nstill passes `ifStatus` draft.\nIt guards the lifecycle, for example a draft to sent promotion against a\nconcurrent promotion. It does NOT serialize two edits of the same draft:\nconcurrent writers that all send ifStatus draft all succeed and the last\none wins. ifUpdatedAt narrows that window only partly (see its limitation).\n"
},
"ifUpdatedAt": {
"type": "string",
"maxLength": 64,
"writeOnly": true,
"description": "The `updatedAt` value of the invoice, as returned by a previous GET.\nIt is an exact string comparison, not a date comparison (surrounding\nwhitespace is trimmed first): an equivalent instant in another format (no\nmilliseconds, a +01:00 offset) returns 409.\nA value that is not shaped like an ISO 8601 timestamp (date, time and zone;\nfor example month 13) is a 400, so a legacy updatedAt in another format\ncannot be echoed. A well-shaped value that is not a real calendar date, such\nas 2026-02-31T10:00:00Z, is not a 400: it never equals a stored token and\nreturns 409.\nLimitation: this is NOT a general guard against concurrent edits.\n`updatedAt` is not a complete revision counter. It detects only writes that\nraise `updatedAt`. Edits made from the Frihet app or the in-app assistant\nmay not raise it (the app writes the invoice as is, without refreshing\n`updatedAt`), and Payment Authority settlements, invoice amendments and\ndeposits do not either. A match therefore proves only that no\nupdatedAt-raising write happened since the token was read; it can still be\n200 after a person edited the same draft in the app, and an older write can\nrestore an earlier token. An invoice that has no stored `updatedAt` has no\ntoken: GET returns none and every ifUpdatedAt returns 409 with\n`actualUpdatedAt` null. Pair ifUpdatedAt with ifStatus for lifecycle\nsafety; do not rely on it to protect edits.\n"
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/frihet-io-invoice-update-preconditions"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.