NewProvince is only required for addresses in Spain
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog

Handling AEAT rejections

How to read a REJECTED invoice (and an accepted one that carries an error code), what to do for each family of AEAT codes, and how to make sure you never miss one.


A registered invoice is immutable, so a rejection is resolved with a new fiscal document or, when the cause lies outside the invoice, by contacting BeeL. This page tells you which, from what the invoice says.

For the full state machine, see Submission states. For choosing between a corrective and a void, see Cancel vs amend.

Read the invoice first

Three fields on the invoice's verifactu block tell you where you are: submission_status, error_code and error_message.

submission_statuserror_codeWhat happenedGo to
REJECTEDsetAEAT answered with a coded rejectionAEAT codes by what to do
REJECTEDabsentAEAT gave no coded answer: the submission was refused before it reached AEAT, BeeL. stopped waiting for an answer that never came, or AEAT already holds another invoice with this number. error_message says whichThe number is already taken, otherwise When to contact support
ACCEPTEDsetAccepted with errors: the invoice is registered, but AEAT flagged some of its dataAccepted with errors
ACCEPTEDabsentRegistered cleanlyNothing to do
NOT_SUBMITTED—The invoice should have gone to AEAT and has no record at allWhen to contact support

error_message is for humans. Show it, log it, attach it to a support request — never parse it or branch on its wording. Its language and phrasing are not stable, and it is not always AEAT's text: when AEAT gave no answer, BeeL. writes its own explanation there. Branch on submission_status and error_code only.

To see each record separately — the registration and, if you voided, the cancellation — use List the VeriFactu records of an invoice. Each record carries its own submission_status and, read the same way as on the invoice, its own error_message and error_code.

A temporary AEAT error stays PENDING

When AEAT answers with a temporary server-side error, the invoice is not rejected: it stays PENDING, with no error_code or error_message, while BeeL. retries it, and no verifactu.status.updated is sent. It moves to ACCEPTED or REJECTED when AEAT gives a real answer, or to REJECTED if the retries run out:

PENDING  →  (AEAT server-side error; BeeL. retries, still PENDING)  →  ACCEPTED or REJECTED

So a REJECTED invoice does not move on its own: it is safe to act on it.

Accepted with errors

ACCEPTED with an error_code means AEAT registered the invoice but reported a problem with some of its data. The invoice is valid and in AEAT's registry; you do not need to resubmit it, and it will not change on its own.

A typical cause is the recipient: AEAT could not match the recipient's NIF and name against its census. That can happen when the customer's NIF could not be checked against the census at the time the customer was saved — BeeL. lets the customer through rather than block you, and AEAT flags it later.

What to do:

  1. Read error_message to see what AEAT flagged.
  2. Check that data — usually the recipient's NIF and legal name — against the customer's real details.
  3. If it was right, nothing else is needed. If it was wrong, fix it in the customer's data so the following invoices carry it right. A corrective does not change it on the invoice already recorded: it keeps the recipient of the invoice it corrects (COR-017 A corrective keeps the recipient, except to correct the recipient's data). See REC-009 Check the data AEAT accepted with errors.

AEAT codes by what to do

error_code carries AEAT's code unchanged. These are the codes you are most likely to meet, grouped by who has to act. AEAT has many more; the complete list is in the AEAT VeriFactu documentation.

Recipient data — fix the invoice

CodeMeaning
1109 / 1110A NIF on the invoice is not in the AEAT census
1123The NIF format is incorrect
1193The recipient's NIF is not identified, or equals the issuer's
1149Under regime key 14, the recipient's NIF must be in the census and start with P, Q, S or V

What to do: check the recipient against the census with the NIF validation API and fix the customer record. A corrective is not the way: the rejected invoice is not in AEAT's registry, and correcting it answers CORRECTIVE_ORIGINAL_RECORD_REJECTED. Void it — that sends nothing to AEAT; if it was already sent or paid, the void needs issued_in_error: true — and issue a new invoice with the corrected recipient.

The issuer's own setup — fix the NIF, then contact support

CodeMeaning
4104The issuing NIF is not identified in the AEAT census
4107The issuer's NIF is not identified in the AEAT census
4109The issuer's NIF format is incorrect
4112The submission is not authorised for this NIF

What to do: the invoice's data is fine; the taxpayer's situation with AEAT is not. Resolve it — register the NIF with AEAT, or sign the representation — and then contact BeeL. with the invoice. Nothing in the invoice needs correcting, so do not issue a corrective for these.

Suspended access — the taxpayer must talk to AEAT

CodeMeaning
4141AEAT has suspended submission access

What to do: only AEAT can lift it. The taxpayer must contact AEAT; once it is lifted, contact BeeL. with the affected invoices.

Records — usually nothing to fix in the data

CodeMeaningWhat to do
3000Duplicate: AEAT already has a record for this invoiceDo not reissue — the invoice may already be registered. Contact support to reconcile it. A number AEAT holds for a different invoice does not end here: see The number is already taken at AEAT
3001The record has already been cancelledSeen on a cancellation: AEAT already considers the invoice voided. Nothing to redo
3002The record to modify or cancel does not exist in AEATSeen on a cancellation: there is nothing registered to cancel. Contact support if you expected there to be
3003No permission to update this recordContact support

Invoice content — fix the invoice

CodeMeaning
1100A field has an incorrect value or type
1106The invoice type is not allowed
1108The issuer does not match the obligated party
1124The tax rate is not one of the allowed values
1112 / 1133 / 1145 / 1152The issue date is in the future, too old, badly formatted, or earlier than the start of VeriFactu

What to do: issue a corrective with the right data. BeeL. validates most of these before submitting, so they are rare; if you cannot see what is wrong, contact support with the invoice ID.

Record format — contact support

CodeMeaning
4102 / 4103 / 4119The record does not match AEAT's schema, could not be read, or contains characters in the wrong encoding

What to do: these point at how the record was built, not at your data. Contact support with the invoice ID.

Temporary AEAT errors — wait

CodeMeaning
4108 / 4111 / 4128Temporary AEAT technical error
3500 / 3501Temporary AEAT database error
4134 / 4139The AEAT service is not available

What to do: nothing. While BeeL. retries, the invoice stays PENDING and these codes are not published on it. If the retries run out, the invoice becomes REJECTED without an AEAT verdict: contact support.

Reconcile, do not only listen

verifactu.status.updated tells you each time the public status of a record changes, including a submission refused before it reached AEAT or one BeeL. stopped waiting for; NOT_SUBMITTED never produces one, because there is no record to change. Treat the webhook as the fast path and a periodic sweep as the safety net:

# Invoices AEAT does not have
curl "https://app.beel.es/api/v1/companies/{company_id}/invoices?verifactu_status=REJECTED" \
  -H "Authorization: Bearer $BEEL_API_KEY"

# Invoices that should have gone to AEAT and have no record
curl "https://app.beel.es/api/v1/companies/{company_id}/invoices?verifactu_status=NOT_SUBMITTED" \
  -H "Authorization: Bearer $BEEL_API_KEY"

Run it on a schedule (daily is plenty for most volumes), compare with what you already know, and handle anything new as above. There is no need to sweep ACCEPTED invoices: an accepted record never turns into a rejected one — see Is ACCEPTED final?. Keep the job within your rate limits.

NOT_SUBMITTED right after issuing is normal while the submission is in flight; only act on invoices that stay there.

The number is already taken at AEAT

AEAT identifies an invoice by the issuer's NIF, its number and its issue date. If it already holds a record with this invoice's number and date that is not this invoice — typically one issued with the software you used before, under the same NIF — BeeL. does not take that record as this invoice's. The invoice ends REJECTED, with no error_code and an error_message that says the number is taken, and it is not registered. Retrying does not help: it meets the same record. See NUM-002 An issued number is never reused, even when the invoice is voided.

What to do: issue the invoice again with a number AEAT does not hold yet, from another series or a series that continues the sequence of your previous software. The rejected invoice is not in AEAT's registry, so voiding it sends nothing to AEAT — see Cancel vs amend.

Fixing the invoice

When the rejection is about the invoice's data, the fix is always a new fiscal document: a corrective or, for an invoice that should never have been issued, a void. A registered invoice is never edited. Which one fits each situation, including an invoice AEAT never registered, is in the decision matrix of Cancel vs amend.

When to contact support

Write to it@beel.es with the invoice ID(s) and the error_code / error_message you see when:

  • the invoice is REJECTED with no error_code — the record never reached AEAT, or BeeL. gave up waiting — unless error_message says the number is already taken;
  • the invoice stays NOT_SUBMITTED;
  • the cause was outside the invoice (issuer not in the census, representation not signed, suspended access) and you have fixed it;
  • the code is a duplicate (3000), a record-format code, or you cannot tell what is wrong.

When a registration that never reached AEAT — one refused before it got there, or one BeeL. stopped waiting for — is sent again, the new attempt replaces the undelivered one. The invoice keeps its number. In its VeriFactu records, a registration refused before reaching AEAT is listed as REJECTED until the invoice is sent again; the new attempt then takes its place, since the undelivered one was never a record at AEAT.