Manage business invoices

Record the invoices your business issues and receives: the money a customer owes you and the money you owe a supplier. This guide covers both kinds and shows which records feed your tax calculations.

A business invoice is not the same as a purchase receipt you attach as evidence. Receipts support a deductible expense on a ledger transaction (see Attach invoices and receipts). Business invoices recorded here are the commercial documents themselves: an issued invoice (you billed a customer) or a received invoice (a supplier billed you).

Before you start

You need:

  • An active taxpayer profile. Every command below works on the active profile; if none is set, the command refuses. See Set up your taxpayer profile.

  • A master-key passphrase. The tool prompts for it the first time it opens your encrypted storage in a session.

The aeat command-line interface (CLI) emits its help and messages in Spanish; the English text on this page describes what each step does.

Two ways to hold an invoice

Cadrumo keeps invoices in two separate places, for two different jobs.

Your invoices live in one place (aeat app ledger invoice ...): a record of who owes you and whom you owe. Use it to record, list, and edit invoices.

Every invoice you record is linkable and calculable. Match it to a bank transaction with aeat app ledger link, and a calculation reads it directly – for example the Modelo 349 recapitulative declaration of intra-community operations.

Record every invoice with invoice add. There is no second copy to create.

Every command takes --kind issued or --kind received. Issued means a customer owes you (a collectible invoice); received means you owe a supplier (a payable invoice).

Record an issued invoice

Record an invoice you sent to a customer. The command returns the new invoice_id, the resolved source_kind (collectible_invoice), and the values you entered:

1Record an invoice you sent to a customer.
aeat --format json app ledger invoice add --kind issued --counterparty-nif B12345674 \
  --country-code ES --counterparty-name Cliente SL --invoice-number FAC-2026-001 \
  --invoice-date 2026-02-15 --taxable-base 1000 --iva-rate 21
aeat --format json app ledger invoice add --kind issued --counterparty-nif B12345674 `
  --country-code ES --counterparty-name Cliente SL --invoice-number FAC-2026-001 `
  --invoice-date 2026-02-15 --taxable-base 1000 --iva-rate 21
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.add",
  "notices": [],
  "result": {
    "base_total": "1000.00",
    "base_total_eur": "1000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "ES",
    "counterparty_name": "Cliente SL",
    "counterparty_tax_id": "sha256:133cad41",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "1210.00",
    "grand_total_eur": "1210.00",
    "invoice_id": "8156e70ce16a05f4588f7516d49da7ffd4115964a75b079061e624a41ad30211",
    "invoice_number": "FAC-2026-001",
    "issued_at": "2026-02-15",
    "iva_total": "210.00",
    "iva_total_eur": "210.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": null,
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}
2Confirm it resolved to a collectible invoice.
aeat --format json app ledger invoice view {invoice_id}
aeat --format json app ledger invoice view {invoice_id}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.view",
  "notices": [],
  "result": {
    "base_total": "1000.00",
    "base_total_eur": "1000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "ES",
    "counterparty_name": "Cliente SL",
    "counterparty_tax_id": "sha256:133cad41",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "1210.00",
    "grand_total_eur": "1210.00",
    "invoice_id": "8156e70ce16a05f4588f7516d49da7ffd4115964a75b079061e624a41ad30211",
    "invoice_number": "FAC-2026-001",
    "issued_at": "2026-02-15",
    "iva_total": "210.00",
    "iva_total_eur": "210.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": null,
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the issued invoice was stored as a collectible invoice.

Record the short invoice_id; you address the invoice by it (or by an unambiguous prefix).

Record a received invoice

Record an invoice a supplier sent you. The source_kind resolves to payable_invoice:

1Record an invoice a supplier sent you.
aeat --format json app ledger invoice add --kind received --counterparty-nif A87654323 \
  --country-code ES --counterparty-name Proveedor SA --invoice-number PROV-99 \
  --invoice-date 2026-02-20 --taxable-base 500 --iva-rate 21
aeat --format json app ledger invoice add --kind received --counterparty-nif A87654323 `
  --country-code ES --counterparty-name Proveedor SA --invoice-number PROV-99 `
  --invoice-date 2026-02-20 --taxable-base 500 --iva-rate 21
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.add",
  "notices": [],
  "result": {
    "base_total": "500.00",
    "base_total_eur": "500.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "ES",
    "counterparty_name": "Proveedor SA",
    "counterparty_tax_id": "sha256:c1fcd88f",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "605.00",
    "grand_total_eur": "605.00",
    "invoice_id": "2d276305600c31de666ddd61dc33377cde314c59c10f99608db208ec0f46da1b",
    "invoice_number": "PROV-99",
    "issued_at": "2026-02-20",
    "iva_total": "105.00",
    "iva_total_eur": "105.00",
    "kind": "received",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": null,
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}
2Confirm it resolved to a payable invoice.
aeat --format json app ledger invoice view {invoice_id}
aeat --format json app ledger invoice view {invoice_id}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.view",
  "notices": [],
  "result": {
    "base_total": "500.00",
    "base_total_eur": "500.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "ES",
    "counterparty_name": "Proveedor SA",
    "counterparty_tax_id": "sha256:c1fcd88f",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "605.00",
    "grand_total_eur": "605.00",
    "invoice_id": "2d276305600c31de666ddd61dc33377cde314c59c10f99608db208ec0f46da1b",
    "invoice_number": "PROV-99",
    "issued_at": "2026-02-20",
    "iva_total": "105.00",
    "iva_total_eur": "105.00",
    "kind": "received",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": null,
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the received invoice was stored as a payable invoice.

List, view, update, and remove

List both kinds or filter to one, add a note to a stored invoice, then remove it. The view of one invoice takes its id (or an unambiguous prefix) and the kind:

1List every invoice, both kinds.
aeat app ledger invoice list
aeat app ledger invoice list
bucket	<profile-id>
count	1
876198eb9b01ec6643765dd6bb7141567df25dc89e280632bffce3f8f9d3e9f9	issued	sha256:133cad41	FAC-2026-050	2026-02-15	1210.00
2Filter the list to issued invoices only.
aeat app ledger invoice list --kind issued
aeat app ledger invoice list --kind issued
bucket	<profile-id>
count	1
876198eb9b01ec6643765dd6bb7141567df25dc89e280632bffce3f8f9d3e9f9	issued	sha256:133cad41	FAC-2026-050	2026-02-15	1210.00
3Add a note to the invoice.
aeat app ledger invoice update {invoice_id} --notes paid late
aeat app ledger invoice update {invoice_id} --notes paid late
invoice_id	876198eb9b01ec6643765dd6bb7141567df25dc89e280632bffce3f8f9d3e9f9
kind	issued
counterparty_name	Cliente SL
counterparty_tax_id	sha256:133cad41
invoice_number	FAC-2026-050
issued_at	2026-02-15
base_total	1000.00
iva_total	210.00
grand_total	1210.00
currency	EUR
operation_type	
invoice_class	ORDINARIA
series	
rectifies_invoice_number	
recargo_amount	
iva_category	
linked_transaction_ids	
bucket_event_ids	d4fee17b4a2c566db0b31f44bc80726aca5a9648795c0ae17b933b9cf01b99b0
4Remove the invoice, confirming with --yes.
aeat --format json app ledger invoice remove {invoice_id} --yes
aeat --format json app ledger invoice remove {invoice_id} --yes
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.remove",
  "notices": [],
  "result": {
    "base_total": "1000.00",
    "base_total_eur": "1000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "ES",
    "counterparty_name": "Cliente SL",
    "counterparty_tax_id": "sha256:133cad41",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "1210.00",
    "grand_total_eur": "1210.00",
    "invoice_id": "876198eb9b01ec6643765dd6bb7141567df25dc89e280632bffce3f8f9d3e9f9",
    "invoice_number": "FAC-2026-050",
    "issued_at": "2026-02-15",
    "iva_total": "210.00",
    "iva_total_eur": "210.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "paid late",
    "operation_type": null,
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the note was added and the invoice then removed.

Record an intra-community invoice

A supply to, or acquisition from, a VAT-registered business in another EU country is an intra-community operation. Record it on the issued or received invoice with the counterparty’s country and EU VAT id, plus the Modelo 349 operation type:

1Record a supply to a VAT-registered EU customer with its M349 operation type.
aeat --format json app ledger invoice add --kind issued --counterparty-nif DE345678901 \
  --counterparty-name Kunde GmbH --invoice-number EU-001 --invoice-date 2026-02-10 \
  --taxable-base 2000 --iva-rate 0 --country-code DE --operation-type E
aeat --format json app ledger invoice add --kind issued --counterparty-nif DE345678901 `
  --counterparty-name Kunde GmbH --invoice-number EU-001 --invoice-date 2026-02-10 `
  --taxable-base 2000 --iva-rate 0 --country-code DE --operation-type E
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.add",
  "notices": [],
  "result": {
    "base_total": "2000.00",
    "base_total_eur": "2000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "DE",
    "counterparty_name": "Kunde GmbH",
    "counterparty_tax_id": "sha256:a9224776",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "2000.00",
    "grand_total_eur": "2000.00",
    "invoice_id": "6d5fa3b4e91913a5e2f8245f40061fe824ecb7894c88b418d6e8c0fb1be79ca7",
    "invoice_number": "EU-001",
    "issued_at": "2026-02-10",
    "iva_total": "0.00",
    "iva_total_eur": "0.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": "E",
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}
2Confirm the operation type and country were stored.
aeat --format json app ledger invoice view {invoice_id}
aeat --format json app ledger invoice view {invoice_id}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.view",
  "notices": [],
  "result": {
    "base_total": "2000.00",
    "base_total_eur": "2000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "DE",
    "counterparty_name": "Kunde GmbH",
    "counterparty_tax_id": "sha256:a9224776",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "2000.00",
    "grand_total_eur": "2000.00",
    "invoice_id": "6d5fa3b4e91913a5e2f8245f40061fe824ecb7894c88b418d6e8c0fb1be79ca7",
    "invoice_number": "EU-001",
    "issued_at": "2026-02-10",
    "iva_total": "0.00",
    "iva_total_eur": "0.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": "E",
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}

Confirm the operation type and country were stored on the issued invoice.

--operation-type takes one M349 operation key: E supplies of goods, M supplies after an exempt import, H the same via a fiscal representative, A acquisitions of goods, T triangular supplies, S services supplied, I services acquired, and the call-off-stock keys R (transfers), D (returns), and C (substitutions).

Feed a calculation from the catalogue

To make an invoice reach a modelo calculation, create it in the catalogue. The catalogue copy is the one a calculation reads and the one you can link to a bank transaction. The sequence catalogues an intra-community supply, lists and inspects the catalogue, then creates and calculates the Modelo 349 recapitulative declaration for the period the invoice falls in:

1Catalogue an intra-community supply so a calculation can read it.
aeat --format json app ledger invoice add --kind issued --counterparty-nif DE345678901 \
  --counterparty-name Kunde GmbH --invoice-number EU-CAT-001 --invoice-date 2026-02-10 \
  --taxable-base 2000 --iva-rate 0 --country-code DE --operation-type E
aeat --format json app ledger invoice add --kind issued --counterparty-nif DE345678901 `
  --counterparty-name Kunde GmbH --invoice-number EU-CAT-001 --invoice-date 2026-02-10 `
  --taxable-base 2000 --iva-rate 0 --country-code DE --operation-type E
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.add",
  "notices": [],
  "result": {
    "base_total": "2000.00",
    "base_total_eur": "2000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "DE",
    "counterparty_name": "Kunde GmbH",
    "counterparty_tax_id": "sha256:a9224776",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "2000.00",
    "grand_total_eur": "2000.00",
    "invoice_id": "5f6226984e838fa553b9647364c5e3199cb833d79c8932072b9a67bc39eabc17",
    "invoice_number": "EU-CAT-001",
    "issued_at": "2026-02-10",
    "iva_total": "0.00",
    "iva_total_eur": "0.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": "E",
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}
2List the catalogue copies.
aeat app ledger invoice list
aeat app ledger invoice list
bucket	<profile-id>
count	1
5f6226984e838fa553b9647364c5e3199cb833d79c8932072b9a67bc39eabc17	issued	sha256:a9224776	EU-CAT-001	2026-02-10	2000.00
3Inspect one catalogue invoice to confirm its id.
aeat --format json app ledger invoice view {invoice_id}
aeat --format json app ledger invoice view {invoice_id}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "ledger.invoice.view",
  "notices": [],
  "result": {
    "base_total": "2000.00",
    "base_total_eur": "2000.00",
    "bucket_id": "<bucket-id>",
    "counterparty_country": "DE",
    "counterparty_name": "Kunde GmbH",
    "counterparty_tax_id": "sha256:a9224776",
    "currency": "EUR",
    "fx_rate": null,
    "fx_rate_date": null,
    "fx_rate_source": null,
    "grand_total": "2000.00",
    "grand_total_eur": "2000.00",
    "invoice_id": "5f6226984e838fa553b9647364c5e3199cb833d79c8932072b9a67bc39eabc17",
    "invoice_number": "EU-CAT-001",
    "issued_at": "2026-02-10",
    "iva_total": "0.00",
    "iva_total_eur": "0.00",
    "kind": "issued",
    "linked_transaction_ids": [],
    "notes": "",
    "operation_type": "E",
    "payment_status": "PENDING",
    "recargo_amount": null,
    "retention_amount": null,
    "retention_rate": null
  },
  "schema_version": "2",
  "status": "success"
}
4Create the Modelo 349 work unit for the period the invoice falls in.
aeat --format json app modelo work create --modelo 349 --year 2026 --period 02
aeat --format json app modelo work create --modelo 349 --year 2026 --period 02
{
  "active_profile": "docs-sequence-sandbox",
  "command": "modelo.work.create",
  "notices": [],
  "result": {
    "applicability_guard_bypassed": false,
    "bucket_id": "<bucket-id>",
    "causante_ccaa": null,
    "created_at": "2026-04-01T09:00:00+00:00",
    "current_calculation_revision_id": null,
    "current_filing_record_id": null,
    "discard_reason": null,
    "discarded_at": null,
    "discarded_by": null,
    "filed_calculation_revision_id": null,
    "filing_year": 2026,
    "modelo": "349",
    "name": "349-2026-02",
    "name_applied": null,
    "operation": "modelo.work.create",
    "period": {
      "code": "02",
      "filing_year": 2026
    },
    "revision_id": "2020-y-siguientes",
    "short_current_calculation_revision_id": null,
    "short_filed_calculation_revision_id": null,
    "short_work_unit_id": "253f06e07c9f",
    "state": "borrador",
    "status": "created",
    "status_message": "New work unit created.",
    "updated_at": "2026-04-01T09:00:00+00:00",
    "work_unit_id": "1609deb31dbe07e1b21281e26d114d5a4ef4230a5e9d2f387e8c253f06e07c9f"
  },
  "schema_version": "2",
  "status": "success"
}
5Calculate the recapitulative declaration.
aeat --format json app modelo work calculate {work_unit_id}
aeat --format json app modelo work calculate {work_unit_id}
{
  "active_profile": "docs-sequence-sandbox",
  "command": "modelo.work.calculate",
  "notices": [
    {
      "action": null,
      "code": "modelo.work.calculate.plazo_vencido_unassessed_preview",
      "context": {
        "article_27_assessment_status": "unassessed",
        "closes_on": "2026-03-20",
        "conditional_recargo_preview_band": "completed_months_0",
        "conditional_recargo_preview_interest_applies": "False",
        "conditional_recargo_preview_pct": "1.00",
        "conditional_recargo_preview_reference_on": "2026-04-01",
        "days_overdue": "12",
        "legal_refs": "ley-58-2003:art-27.2"
      },
      "message": "WARNING: voluntary filing period expired (Art. 27 LGT). The displayed rate is an unassessed preview; this application does not determine surcharge or interest liability.",
      "severity": "warning"
    }
  ],
  "result": {
    "authorization_state": null,
    "binding_overrides": {
      "iva-349-declarante-importe-operaciones": "2000",
      "iva-349-declarante-importe-operaciones-adquisicion": "0",
      "iva-349-declarante-importe-rectificaciones": "0",
      "iva-349-declarante-importe-rectificaciones-adquisicion": "0",
      "iva-349-declarante-numero-operadores": "1",
      "iva-349-declarante-numero-operadores-adquisicion": "0",
      "iva-349-declarante-numero-rectificaciones": "0",
      "iva-349-declarante-numero-rectificaciones-adquisicion": "0",
      "modelo-349-ledger-intracommunity-guard": "0"
    },
    "calculation_revision_id": "457438fde19c986c6e759c496965856b1141a8aaf23c3f9eb6ca82967b7daf43",
    "casilla_values": {
      "decl.cambio-periodicidad": "0",
      "decl.complementaria-sustitutiva": "0",
      "decl.importe-operaciones": "2000.00",
      "decl.importe-rectificaciones": "0",
      "decl.nif-representante-legal": "0",
      "decl.numero-identificativo": "0",
      "decl.numero-identificativo-anterior": "0",
      "decl.numero-operadores": "1",
      "decl.numero-rectificaciones": "0",
      "sustituto.apellidos-razon-social": "0",
      "sustituto.nif": "0"
    },
    "created_at": "2026-04-01T09:00:00+00:00",
    "deadline": {
      "closes_on": "2026-03-20",
      "conditional_recargo_preview": {
        "assessment_status": "unassessed",
        "band_id": "completed_months_0",
        "interest_applies": false,
        "legal_ref": "ley-58-2003:art-27.2",
        "rate_reference_on": "2026-04-01",
        "surcharge_pct": "1.00"
      },
      "days_overdue": 12,
      "days_remaining": null
    },
    "detail_rows": [
      {
        "fields": {
          "clave_operacion": "E",
          "codigo_pais": "DE",
          "importe": "2000.00",
          "nif_comunitario": "sha256:a9224776",
          "razon_social": "Kunde GmbH"
        },
        "index": 1,
        "row_type": "operador"
      }
    ],
    "filed_at": null,
    "filed_by": null,
    "input_values_by_casilla_id": {
      "decl.importe-operaciones": "2000",
      "decl.importe-rectificaciones": "0",
      "decl.numero-operadores": "1",
      "decl.numero-rectificaciones": "0"
    },
    "modality": null,
    "modality_reason": null,
    "observations": [
      {
        "absent_by_design": false,
        "casilla_id": "decl.cambio-periodicidad",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93",
          "rd-1624-1992:art-81"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.complementaria-sustitutiva",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93",
          "rd-1624-1992:art-81"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.importe-operaciones",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current",
          "aeat-modelo-349-procedure"
        ],
        "value": "2000.00"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.importe-rectificaciones",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current",
          "aeat-modelo-349-procedure"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.nif-representante-legal",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93",
          "rd-1624-1992:art-81"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.numero-identificativo",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93",
          "rd-1624-1992:art-81"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.numero-identificativo-anterior",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93",
          "rd-1624-1992:art-81"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.numero-operadores",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current",
          "aeat-modelo-349-procedure"
        ],
        "value": "1"
      },
      {
        "absent_by_design": false,
        "casilla_id": "decl.numero-rectificaciones",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current",
          "aeat-modelo-349-procedure"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "sustituto.apellidos-razon-social",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      },
      {
        "absent_by_design": false,
        "casilla_id": "sustituto.nif",
        "formula_id": null,
        "legal_refs": [
          "orden-eha-769-2010:art-1",
          "orden-hac-174-2020:art-1",
          "ley-58-2003:art-93"
        ],
        "op": null,
        "operand_casilla_refs": [],
        "operand_refs": [],
        "operand_values": [],
        "source_refs": [
          "aeat-dr-349-2020-current"
        ],
        "value": "0"
      }
    ],
    "operation": "modelo.work.calculate",
    "registry_snapshot_ref": {
      "modelo": "349",
      "modelo_year": 2026,
      "period": "02",
      "revision_id": "2020-y-siguientes"
    },
    "relation_overrides": {},
    "result_summary": [
      {
        "casilla_id": "decl.numero-operadores",
        "label": "Total number of intra-Community operators",
        "role": "key_figure",
        "value": "1"
      },
      {
        "casilla_id": "decl.importe-operaciones",
        "label": "Amount of intra-Community transactions",
        "role": "key_figure",
        "value": "2000.00"
      }
    ],
    "saved": true,
    "saved_confirmation": "Saved as draft calculation revision 457438fde19c986c6e759c496965856b1141a8aaf23c3f9eb6ca82967b7daf43 (state: draft). It is persisted and can be resumed later.",
    "source_provenance": [
      {
        "contributor_binding_source": "collectible_invoice",
        "contributor_source_kind": "collectible_invoice",
        "dependency_treatment": "",
        "fingerprint": "sha256:72748ea0133a321a0f267c1a26c97cb74e46e173732201ddd72a3c2edfd3c890",
        "lineage_role": "primary",
        "parent_source_ref": null,
        "resolved_binding_source": "collectible_invoice",
        "resolver_id": "invoice_catalogue",
        "source_ref": "collectible_invoice:5f6226984e838fa553b9647364c5e3199cb833d79c8932072b9a67bc39eabc17"
      }
    ],
    "state": "borrador",
    "superseded_at": null,
    "updated_at": "2026-04-01T09:00:00+00:00",
    "verified_at": null,
    "verified_by": null,
    "work_unit_id": "1609deb31dbe07e1b21281e26d114d5a4ef4230a5e9d2f387e8c253f06e07c9f"
  },
  "schema_version": "2",
  "status": "warning"
}

Confirm the catalogued invoice reaches the Modelo 349 calculation.

For an intra-community operation, pass --operation-type so the catalogue stamps the classification the Modelo 349 calculation reads. Use E, H, M, S, T, R, D, or C for issued catalogue invoices. Use A, I, or T for received catalogue invoices. In Modelo 349, R is the call-off-stock transfer key; rectification rows use separate rectified-period and base fields.

An invoice is counted only in the period its invoice date falls in. Modelo 349 reads invoices strictly by date, with no carry-forward from earlier periods.

Which modelos read your invoices

Catalogue invoices feed Modelo 349 (the recapitulative declaration of intra-community operations) through the operation type you stamp on them when you create them. This is the modelo your issued and received invoices drive directly.

Your IVA returns do not read these invoice records. Modelo 303 (quarterly IVA) and Modelo 390 (annual IVA summary) are computed from your classified ledger transactions, not from the invoice catalogue. Record the income and expense in the ledger and classify it (see Classify transactions); the IVA returns read the ledger. Recording an invoice here does not add it to a Modelo 303.

Cross-border B2C sales under the One-Stop-Shop scheme (Modelo 369) are a separate flow not yet reachable from invoice add; record those through the OSS-specific workflow.

Where to go next