Quick Start
Introduction
This tutorial runs entirely in the ES sandbox. You will authenticate, register a sandbox Legal Entity, send a Facturae 3.2.2 invoice, and obtain its VERI*FACTU QR.
Sandbox API URL: https://es-sandbox.api.acubeapi.com
No production credentials or real fiscal documents are used in this tutorial.
You will complete three steps:
- Get sandbox access and authenticate.
- Register a new Legal Entity.
- Send an invoice and read its QR.
1. Get sandbox access and authenticate
Create a free sandbox account. To receive an access token, follow the authentication guide.
If the token does not grant access to the ES API, contact A-Cube support.
2. Register a new legal entity
A legal entity represents the Spanish taxpayer you issue invoices for. It is created directly, with no external portal step.
Use POST /legal-entities. Replace
{{jwt}} with the token from step 1. taxId must be a valid Spanish NIF, NIE or CIF
(9 characters, format-checked).
POST /legal-entities
Authorization: Bearer {{jwt}}
Content-Type: application/json
Accept: application/json
{
"taxId": "A58818501",
"name": "A-Cube Test Company",
"email": "test@acme.test",
"phoneNumber": "+34600000000",
"country": "ES",
"address": "Calle Mayor 1",
"city": "Madrid",
"stateOrProvince": "Madrid",
"zipCode": "28001",
"config": {
"supplierInvoiceEnabled": true,
"customerInvoiceEnabled": true
}
}
{
"uuid": "01a047df-a310-75f9-8176-b9370c82a850",
"taxId": "A58818501",
"name": "A-Cube Test Company",
"status": "legal_entity.onboarding_completed",
"config": { "supplierInvoiceEnabled": true, "customerInvoiceEnabled": true },
"createdAt": "2026-08-28T10:17:13+00:00",
"updatedAt": null
}
customerInvoiceEnabled must be true for the entity to issue invoices. Save the
uuid and the taxId, since you will use the tax id as the invoice sender.
3. Send an invoice
3.1 Send a Facturae 3.2.2 invoice
Prepare a valid Facturae document whose SellerParty tax id is the taxId of the legal
entity you just registered, and post it to
POST /invoices. The example below uses
XML; you can send the equivalent JSON
with Content-Type: application/json instead.
POST /invoices
Authorization: Bearer {{jwt}}
Content-Type: application/xml
Accept: application/json
<?xml version="1.0" encoding="UTF-8"?>
<fe:Facturae xmlns:fe="http://www.facturae.gob.es/formato/Versiones/Facturaev3_2_2.xml" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<FileHeader>
<SchemaVersion>3.2.2</SchemaVersion>
<Modality>I</Modality>
<InvoiceIssuerType>EM</InvoiceIssuerType>
<Batch>
<BatchIdentifier>A58818501-FV-2026-0001</BatchIdentifier>
<InvoicesCount>1</InvoicesCount>
<TotalInvoicesAmount><TotalAmount>1452.00</TotalAmount></TotalInvoicesAmount>
<TotalOutstandingAmount><TotalAmount>1452.00</TotalAmount></TotalOutstandingAmount>
<TotalExecutableAmount><TotalAmount>1452.00</TotalAmount></TotalExecutableAmount>
<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode>
</Batch>
</FileHeader>
<Parties>
<SellerParty>
<TaxIdentification>
<PersonTypeCode>J</PersonTypeCode>
<ResidenceTypeCode>R</ResidenceTypeCode>
<TaxIdentificationNumber>A58818501</TaxIdentificationNumber>
</TaxIdentification>
<LegalEntity>
<CorporateName>SupplierOfficialName Ltd.</CorporateName>
<AddressInSpain>
<Address>Calle Mayor 1</Address>
<PostCode>28001</PostCode>
<Town>Madrid</Town>
<Province>Madrid</Province>
<CountryCode>ESP</CountryCode>
</AddressInSpain>
</LegalEntity>
</SellerParty>
<BuyerParty>
<TaxIdentification>
<PersonTypeCode>J</PersonTypeCode>
<ResidenceTypeCode>R</ResidenceTypeCode>
<TaxIdentificationNumber>B12345674</TaxIdentificationNumber>
</TaxIdentification>
<LegalEntity>
<CorporateName>Buyer Official Name</CorporateName>
<AddressInSpain>
<Address>Calle Alcala 20</Address>
<PostCode>28014</PostCode>
<Town>Madrid</Town>
<Province>Madrid</Province>
<CountryCode>ESP</CountryCode>
</AddressInSpain>
</LegalEntity>
</BuyerParty>
</Parties>
<Invoices>
<Invoice>
<InvoiceHeader>
<InvoiceNumber>FV-2026-0001</InvoiceNumber>
<InvoiceDocumentType>FC</InvoiceDocumentType>
<InvoiceClass>OO</InvoiceClass>
</InvoiceHeader>
<InvoiceIssueData>
<IssueDate>2026-01-15</IssueDate>
<InvoiceCurrencyCode>EUR</InvoiceCurrencyCode>
<TaxCurrencyCode>EUR</TaxCurrencyCode>
<LanguageName>es</LanguageName>
</InvoiceIssueData>
<TaxesOutputs>
<Tax>
<TaxTypeCode>01</TaxTypeCode>
<TaxRate>21.00</TaxRate>
<TaxableBase><TotalAmount>1200.00</TotalAmount></TaxableBase>
<TaxAmount><TotalAmount>252.00</TotalAmount></TaxAmount>
</Tax>
</TaxesOutputs>
<InvoiceTotals>
<TotalGrossAmount>1200.00</TotalGrossAmount>
<TotalGrossAmountBeforeTaxes>1200.00</TotalGrossAmountBeforeTaxes>
<TotalTaxOutputs>252.00</TotalTaxOutputs>
<TotalTaxesWithheld>0.00</TotalTaxesWithheld>
<InvoiceTotal>1452.00</InvoiceTotal>
<TotalOutstandingAmount>1452.00</TotalOutstandingAmount>
<TotalExecutableAmount>1452.00</TotalExecutableAmount>
</InvoiceTotals>
<Items>
<InvoiceLine>
<ItemDescription>Servicios de consultoria</ItemDescription>
<Quantity>1</Quantity>
<UnitPriceWithoutTax>1200.00</UnitPriceWithoutTax>
<TotalCost>1200.00</TotalCost>
<GrossAmount>1200.00</GrossAmount>
<TaxesOutputs>
<Tax>
<TaxTypeCode>01</TaxTypeCode>
<TaxRate>21.00</TaxRate>
<TaxableBase><TotalAmount>1200.00</TotalAmount></TaxableBase>
<TaxAmount><TotalAmount>252.00</TotalAmount></TaxAmount>
</Tax>
</TaxesOutputs>
</InvoiceLine>
</Items>
<PaymentDetails>
<Installment>
<InstallmentDueDate>2026-02-14</InstallmentDueDate>
<InstallmentAmount>1452.00</InstallmentAmount>
<PaymentMeans>04</PaymentMeans>
</Installment>
</PaymentDetails>
</Invoice>
</Invoices>
</fe:Facturae>
{
"uuid": "01a03e4a-ee3a-7e1f-b372-c8382bd4ec73",
"invoiceNumber": "FV-2026-0001",
"invoiceDate": "2026-01-15",
"dueDate": "2026-02-14",
"currency": "EUR",
"totalAmount": "1452.00",
"netAmount": "1200.00",
"direction": "outgoing",
"sender": { "name": "SupplierOfficialName Ltd.", "fiscalId": "A58818501" },
"recipient": { "name": "Buyer Official Name", "fiscalId": "B12345674" },
"status": "accepted",
"errorReason": null,
"downloaded": false,
"downloadedAt": null
}
To test your error handling, set the BuyerParty tax id to one of the
reserved sandbox values
(for example ESSANDBOXERR0002 for a duplicate-number rejection).
3.2 Read the VERI*FACTU QR
GET /invoices/01a03e4a-ee3a-7e1f-b372-c8382bd4ec73/qr
Authorization: Bearer {{jwt}}
Accept: application/json
{
"url": "https://prewww2.aeat.es/wlpl/TIKE-CONT/ValidarQR?nif=A58818501&numserie=FV-2026-0001&fecha=15-01-2026&importe=1452.00",
"nif": "A58818501",
"seriesNumber": "FV-2026-0001",
"issueDate": "15-01-2026",
"totalAmount": "1452.00"
}
Request it with Accept: image/png to get the QR as an image. See
VERI*FACTU QR.
3.3 (Optional) Build it as a draft first
Instead of sending in one shot, you can
POST /invoices/draft with partial
content (only Parties is required), refine it with
PUT /invoices/draft/{uuid}, then
POST /invoices/draft/{uuid}/send.
3.4 List your invoices
GET /invoices?direction=outgoing&order[invoiceDate]=desc
Authorization: Bearer {{jwt}}
Accept: application/json
See Search documents for the full filter set.
You can now authenticate, register a sandbox entity, and issue a Facturae invoice with its VERI*FACTU QR.