Fiscal cookbook
Six end-to-end recipes — issue and wait for AEAT acceptance, correct an amount, substitute simplified invoices, pass on a disbursement, invoice outside the EU, and repair a rejected record.
Every recipe below is a complete sequence of calls, with the factuarea CLI
equivalent, and a link to the guide that explains why it is done that way.
The guides carry the fiscal reasoning; this page carries the order of operations.
The CLI command tree is generated from the OpenAPI document, so every endpoint
is reachable either as a named command or through the generic escape hatch
factuarea api <method> <path>. The recipes use the escape hatch wherever the
named form would be guesswork; both hit the same v1 endpoint. See
CLI usage.
Set your key once:
export FACTUAREA_KEY="fact_live_3pXnR2VbY7TcA9eFmN5z8KqW"How this page relates to the other four questions
Each fiscal guide answers four questions about its scenario. This page is a recipe book, so it answers them by delegation, and says so rather than omitting the sections.
When each recipe applies
Stated at the top of each recipe as its goal. The preconditions — which invoice status admits which operation, which document types are eligible — belong to the linked guide and are not restated here.
What the API sends
This is the only dimension the page covers in full: every recipe shows the complete request and its CLI equivalent, with real field names from the v1 contract.
What appears on the PDF
Not covered here. No recipe changes the printed document beyond what its guide already describes — the legal QR block, the disbursement rows in the totals block, the corrective's own numbering. See Disbursements and Corrective invoices.
What reaches the AEAT
Not covered here. The declarations produced by these sequences are described in VeriFactu submission states and, per scenario, in each linked guide. Recipe 1 is the only one whose purpose is to observe the declaration, and it does so by reading the billing record.
1 · Issue an invoice and wait for AEAT acceptance
Goal: create, issue, and confirm the tax authority registered it.
Create and issue in one call. options.issue_directly saves the separate
send step, and the two events it fires cannot produce a duplicate registration —
the command is idempotent per invoice.
curl -X POST https://api.factuarea.com/v1/invoices \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{
"client_id": "0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42",
"series_id": "019e5584-7a72-7038-a8f6-561ed180b699",
"issued_on": "2026-06-01",
"due_on": "2026-07-01",
"lines": [
{ "description": "Servicio de consultoría", "quantity": 2, "unit_price": 150, "tax_rate": 21, "regime_key": "01" }
],
"options": { "issue_directly": true }
}'factuarea invoices create -d '{"client_id":"…","series_id":"…","issued_on":"2026-06-01","due_on":"2026-07-01","lines":[{"description":"Servicio de consultoría","quantity":2,"unit_price":150,"tax_rate":21,"regime_key":"01"}],"options":{"issue_directly":true}}'Poll the billing record until it leaves the non-final states. Read status
and, once accepted, aeat_csv — that is the value you reconcile against the tax
authority.
curl https://api.factuarea.com/v1/invoices/{invoice_id}/verifactu \
-H "Authorization: Bearer $FACTUAREA_KEY"factuarea api get /v1/invoices/{invoice_id}/verifactu --jsonOr stop polling. Subscribe to the invoice VeriFactu webhook events instead and react when the outcome arrives. See Webhooks.
Fundamentals: VeriFactu auto-submission for the gates that decide whether a record is created at all, and VeriFactu submission states for what each state means.
2 · Correct an amount error
Goal: an issued invoice charged too much. Reduce it without annulling.
A downward correction is a corrective by differences, with negative amounts.
correction_type: "partial" yields that nature; a substitution could not carry a
negative base.
curl -X POST https://api.factuarea.com/v1/invoices/{invoice_id}/corrective \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{
"correction_reason": "error_importe",
"correction_type": "partial",
"lines": [
{ "description": "Ajuste por error de importe", "quantity": -1, "unit_price": 200, "tax_rate": 21 }
]
}'factuarea api post /v1/invoices/{invoice_id}/corrective -d '{"correction_reason":"error_importe","correction_type":"partial","lines":[{"description":"Ajuste por error de importe","quantity":-1,"unit_price":200,"tax_rate":21}]}'Answer: 201 with the new corrective invoice and a Location header. List every
corrective issued against the original with
GET /v1/invoices/{id}/correctives.
Fundamentals: Corrective invoices. If the invoice is still unpaid and the whole document is wrong rather than one amount, check Annul or correct first — annulment may be the right operation.
3 · Substitute simplified invoices with a complete one
Goal: a customer who collected several tickets now needs one deductible invoice.
One call. You pass the recipient and the simplified invoices to aggregate, and get back a complete substitute invoice, already issued:
curl -X POST https://api.factuarea.com/v1/invoices/substitute-simplified \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{
"client_id": "0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42",
"simplified_invoice_ids": [
"0197b1c2-3d4e-7f50-8a61-b2c3d4e5f601",
"0197b1c2-3d4e-7f50-8a61-b2c3d4e5f602"
],
"notes": "Consumos de junio"
}'factuarea api post /v1/invoices/substitute-simplified -d '{"client_id":"…","simplified_invoice_ids":["…","…"],"notes":"Consumos de junio"}'The originals are not annulled: they keep their fiscal status and record that they have been substituted.
Fundamentals: Simplified or full invoices.
4 · Pass on a disbursement
Goal: invoice your fee plus a duty you paid on the customer's behalf, without the duty entering your taxable base.
The disbursement line carries no tax of its own and must carry the origin reference. At least one ordinary line is required alongside it.
curl -X POST https://api.factuarea.com/v1/invoices \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{
"client_id": "0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42",
"series_id": "019e5584-7a72-7038-a8f6-561ed180b699",
"issued_on": "2026-06-01",
"due_on": "2026-07-01",
"lines": [
{ "description": "Honorarios de constitución de sociedad", "quantity": 1, "unit_price": 1000, "tax_rate": 21 },
{ "description": "Tasa del Registro Mercantil", "quantity": 1, "unit_price": 150,
"line_type": "SUPLIDO", "source_invoice_reference": "RM-2026-0451" }
]
}'factuarea invoices create -d '{"client_id":"…","series_id":"…","issued_on":"2026-06-01","due_on":"2026-07-01","lines":[{"description":"Honorarios","quantity":1,"unit_price":1000,"tax_rate":21},{"description":"Tasa del Registro Mercantil","quantity":1,"unit_price":150,"line_type":"SUPLIDO","source_invoice_reference":"RM-2026-0451"}]}'Check the response: total is 1210, total_disbursements is 150 and
total_to_pay is 1360. Charge and reconcile against total_to_pay, not total.
Fundamentals: Disbursements.
5 · Invoice a customer outside the EU
Goal: an export, exempt under art. 21 LIVA.
Create the customer with an alternative identification. The type must be legal for the country — an intra-community VAT number is not.
curl -X POST https://api.factuarea.com/v1/clients \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Acme Inc",
"alternative_id": { "type": "passport", "value": "X1234567", "country_code": "US" }
}'Issue with the exemption declared per line. The header regime is read-only over the public API, so the exemption is stated on the line:
curl -X POST https://api.factuarea.com/v1/invoices \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{
"client_id": "{client_id}",
"series_id": "019e5584-7a72-7038-a8f6-561ed180b699",
"issued_on": "2026-06-01",
"due_on": "2026-07-01",
"notes": "Operación exenta por exportación (art. 21 LIVA)",
"lines": [
{ "description": "Suministro de equipos", "quantity": 1, "unit_price": 4000,
"tax_rate": 0, "exemption_reason": "E2", "regime_key": "02" }
]
}'Fundamentals: International customers — and read its note on reverse charge before assuming the same shape works for services.
6 · Repair a record the AEAT rejected
Goal: the tax authority refused the declaration because of a data error. Fix it without annulling the invoice.
Confirm it is a rejection, not a technical failure. A rejected status means
the AEAT read the declaration; error means it never arrived and is retried
automatically.
curl "https://api.factuarea.com/v1/verifactu/records?status=rejected" \
-H "Authorization: Bearer $FACTUAREA_KEY"Fix the data at its source. The declaration is regenerated from the invoice and the current master data — correct the customer's tax ID or registered name and the new values are picked up.
curl -X PUT https://api.factuarea.com/v1/clients/{client_id} \
-H "Authorization: Bearer $FACTUAREA_KEY" \
-H "Content-Type: application/json" \
-d '{"tax_id": "B12345678"}'Resubmit. No request body: the content is regenerated server-side.
curl -X POST https://api.factuarea.com/v1/verifactu/records/{record_id}/subsanar \
-H "Authorization: Bearer $FACTUAREA_KEY"factuarea api post /v1/verifactu/records/{record_id}/subsanar --jsonWatch the outcome. The record is transmitted again and ends accepted — or rejected once more if the data is still wrong, in which case you can repeat. There is no attempt limit on this path.
If the answer is 422 telling you an annulment is required, the correction
touches a fingerprint field — the total, the number, the date, the issuer tax ID
or the invoice type — and the record cannot be repaired in place.
Fundamentals: VeriFactu record subsanación for the full error table, and VeriFactu submission states for retry versus subsanación.
Traceability
This page states no fiscal rule of its own: it sequences calls whose grounds are established elsewhere. Each recipe inherits the traceability of the guide it links:
| Recipe | Inherits from |
|---|---|
| Issue and wait | VeriFactu auto-submission · VeriFactu submission states |
| Correct an amount | Corrective invoices · Annul or correct |
| Substitute simplified | Simplified or full invoices |
| Pass on a disbursement | Disbursements |
| Invoice outside the EU | International customers · Line tax classification and exemptions |
| Repair a rejected record | VeriFactu submission states |