Create and Send Invoice
POST/api/v1/invoices
Submit an invoice using the Canonical Invoice Model (human-friendly JSON format). The system will:
- Validate against business, country, and BIS rules
- Transform to Peppol BIS 3.0 UBL XML
- Queue for AS4 transmission to recipient
No Peppol XML knowledge required - just provide invoice data in JSON.
Returns transaction ID for tracking delivery status.
There is no dry run here: validate_only: true is refused with 422
VALIDATE_ONLY_NOT_SUPPORTED before anything is created or sent. To check an
invoice without sending it, use POST /api/v1/invoices/validate. Production
(app.goroute.ai) takes this refusal in a later release than the test
environment; a deployment without it ignores validate_only and sends the
invoice, so never set it expecting a dry run.
There is no "send later" here either, and the body carries no idempotency key.
Each is refused with 422 before anything is created or sent, whether it is at
the top level or under an options object:
send_immediatelyother thantrue:SEND_IMMEDIATELY_NOT_SUPPORTED. To keep an invoice and send it later, create a draft (POST /api/v1/drafts) and send it withPOST /api/v1/drafts/{draft_id}/send.idempotency_key:IDEMPOTENCY_KEY_IN_BODY_NOT_SUPPORTED. Send the key in theIdempotency-Keyheader, the only place it is read. A bodyidempotency_keyequal to that header is accepted: the header deduplicates the request.
Production takes these two refusals in the same later release: until then it
ignores both fields, so send_immediately: false sends the invoice at once
and a body idempotency_key does not stop a duplicate.
An invoice that fails validation is not sent. It is answered with status
validation_failed and the errors under validation.errors: with HTTP 202 by
default, or, where the platform answers it with 422
(INVOICE_VALIDATION_FAILED_STATUS), with HTTP 422 and the same body plus a
detail block (error validation_failed, error_code INVOICE_INVALID,
errors). Where the platform enforces the official rules (the UBL XSD and the
Schematron of the rendered document's customisation), an invoice they refuse
is answered the same way, one error per rule.
A retry with the same Idempotency-Key header (within 24 hours, for the same
request) is a replay: it answers the first send's transaction_id, that
transaction's status as it is now, the message
Invoice already accepted (idempotent replay) and the document_number and
document_uuid the first send recorded. Nothing is sent twice. A replay is not
validated again, so its validation is null (production, until it takes the
same later release, validates it again and returns that result). The same key
with a different request is refused with 422 IDEMPOTENCY_KEY_REUSED.
The same invoice (same seller, type, number, issue date and tax totals) is sent
once, whatever Idempotency-Key carries it: sent again under another key it is
refused with 409 SAME_DOCUMENT_EXISTS naming the first transaction. When that
send failed, an invoice a tax authority is told about (an Omani one) is refused
with SAME_DOCUMENT_FAILED and its /retry; any other goes again as a new
transaction (a corrected buyer, say). Sent again without a key, it is answered
with the first transaction. Two sends of one invoice at the same moment are
taken one after the other; one still waiting after a minute is refused with
409 SAME_DOCUMENT_IN_FLIGHT (retryable).
Requestโ
Responsesโ
- 202
- 422
Successful Response
Validation Error