Errors & reason codes
Every unfavourable answer names a code from the published catalogue, with a message an officer can read and — where the taxpayer can fix it — a remediation link that works.
Reading a refusal
{
"ok": false,
"verification_id": null,
"timestamp": "2026-09-14T09:12:44+01:00",
"request": { "id": "a71f3c9d2b40", "client": "CLI-2026-004417", "env": "sandbox", "echo": {} },
"error": {
"code": "TCC_STALE_FOR_YEAR",
"title": "Tax clearance certificate not current for this year",
"message": "A 2025 certificate does not satisfy a transaction in 2026. A current certificate is required.",
"remediation_url": "https://services.abiastate.gov.ng/remediate/9f3c1d7a4b2e",
"retryable": false,
"details": { "tcc_year": 2025, "year": 2026 }
}
} - Branch on code. Codes are additive and never renamed. Messages are written for a human to read and will be improved.
- Show message. It is already filled in with the subject — the director's name, the amount, the year — and is safe to put in front of an officer or a taxpayer.
- Offer remediation_url. Where it is present it opens a working page for the taxpayer. A refusal with a dead end is a refusal that gets worked around at the counter.
- Respect retryable. False means the identical call will never succeed; something has to change first.
- Read details when you want the numbers behind the sentence — computed and paid amounts, the failing subject, the gate.
- An unknown code is possible: the catalogue grows. Treat one you do not recognise as a refusal, show the message, and log the code.
HTTP status is advisory; the envelope is authoritative. In particular an internal error is returned as HTTP 200 with ok:false and INTERNAL_ERROR, because the CDN in front of production replaces 5xx bodies with its own page and your client would otherwise be parsing HTML.
The catalogue
54 published codes. Additive only: a code is never renamed or repurposed, and one that is withdrawn is marked deprecated and keeps answering.
| Code | HTTP | Meaning | Remediation | Retry |
|---|---|---|---|---|
| API_DISABLED | 409 |
API disabled
The API is currently disabled.
|
Transient. The identical call may succeed shortly. | yes |
| ASSESSMENT_PENDING_APPROVAL | 409 |
Assessment awaiting approval
An assessment on this transaction is awaiting approval by {role}.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | yes |
| AUTH_INVALID | 401 |
Invalid credentials
The API key was not recognised.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| BR_MISSING | 422 |
Business registration not verified
The business registration (CAC) could not be verified.
|
A revenue officer must look at it; the link opens the case. | no |
| CGT_SHORTFALL | 422 |
Capital gains tax shortfall
Capital gains tax computed at {computed} exceeds the amount paid ({paid}). Balance {balance} is payable.
|
Money is owed; the link opens the bill. | no |
| CGT_UNPAID | 422 |
Capital gains tax unpaid
Capital gains tax of {computed} is payable before this document can issue.
|
Money is owed; the link opens the bill. | no |
| CLIENT_SUSPENDED | 403 |
Client suspended
This client has been suspended. Contact BIR.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| CONTRACT_NOT_FOUND | 404 |
Contract not found
No contract carries final document number {number}.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| DIRECTOR_NONCOMPLIANT | 422 |
Director not compliant
Director {director} has no current tax clearance certificate.
|
A named director or proprietor must regularise before the entity can. | no |
| DIRECTOR_PENDING | 409 |
Director pending
Director {director} is still being verified.
|
A named director or proprietor must regularise before the entity can. | yes |
| DOCUMENT_NOT_FOUND | 404 |
Document not on the register
No document with number {number} exists on the register.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| DOCUMENT_SANDBOX | 200 |
Sandbox document
Number {number} was issued in the integration sandbox. It is a test document and was not issued by Abia State.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| DOCUMENT_VOID | 410 |
Document void
Document {number} was voided on {voided_on}: {reason}.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| FEE_UNPAID | 422 |
Fee unpaid
The agency fee of {computed} is payable.
|
Money is owed; the link opens the bill. | no |
| GATE_PENDING | 409 |
Compliance gates pending
One or more compliance gates are not yet cleared: {gates}.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | yes |
| IDEMPOTENCY_EXPIRED | 409 |
Original response no longer retained
This Idempotency-Key completed earlier and its response has been purged; fetch the resource instead of retrying.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| IDEMPOTENCY_IN_PROGRESS | 409 |
Request in progress
A request with this Idempotency-Key is still being processed.
|
Transient. The identical call may succeed shortly. | yes |
| IDEMPOTENCY_KEY_REQUIRED | 400 |
Idempotency key required
State-changing calls require an Idempotency-Key header.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| IDEMPOTENCY_KEY_REUSED | 409 |
Idempotency key reused
This Idempotency-Key was already used with a different request body.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| INTERNAL_ERROR | 200 |
Internal error
An unexpected error occurred. Retry with the same Idempotency-Key.
|
Transient. The identical call may succeed shortly. | yes |
| IP_NOT_ALLOWED | 403 |
IP not allowed
This client may not call from this address.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| NOT_FOUND | 404 |
Not found
The resource was not found.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| PARTY_AMBIGUOUS | 409 |
Party ambiguous
More than one record matches; supply the ABSSIN.
|
A revenue officer must look at it; the link opens the case. | no |
| PARTY_NOT_FOUND | 404 |
Party not found
No taxpayer record matches the identifier supplied.
|
The party must be registered and given a state identification number. | no |
| PARTY_NO_ABSSIN | 422 |
No ABSSIN
This party has no ABSSIN. Register them to continue.
|
The party must be registered and given a state identification number. | no |
| PARTY_UNREGISTERED | 422 |
Party not registered
The party must be registered (ABSSIN) before the transaction can proceed.
|
The party must be registered and given a state identification number. | no |
| PAYMENT_AMOUNT_MISMATCH | 422 |
Payment amount mismatch
Payment {reference} is for {ledger_amount}, not {amount}.
|
Money is owed; the link opens the bill. | no |
| PAYMENT_DUPLICATE | 409 |
Payment already used
Payment {reference} has already been applied to {txn}.
|
Money is owed; the link opens the bill. | no |
| PAYMENT_HEAD_MISMATCH | 422 |
Payment is for another head
Payment {reference} was posted to a different revenue head.
|
Money is owed; the link opens the bill. | no |
| PAYMENT_NOT_SETTLED | 409 |
Payment not settled
Payment reference {reference} exists but is not yet completed.
|
Money is owed; the link opens the bill. | yes |
| PAYMENT_NO_VERIFICATION | 422 |
No verification for this payment
The verification id cited does not exist; a payment must follow a verification.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| PAYMENT_PARTY_MISMATCH | 422 |
Payment belongs to another taxpayer
Payment {reference} was made by a different taxpayer.
|
Money is owed; the link opens the bill. | no |
| PAYMENT_REF_UNKNOWN | 404 |
Payment reference unknown
Payment reference {reference} was not found in the central ledger.
|
Money is owed; the link opens the bill. | no |
| PROCESS_MDA_MISMATCH | 403 |
Process belongs to another agency
Process {process} is not operated by the calling agency.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| PROCESS_NOT_CONFIGURED | 422 |
Process not configured
Process {process} is not configured for this agency.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| PROPRIETOR_NONCOMPLIANT | 422 |
Proprietor not compliant
Proprietor {director} has no current tax clearance certificate.
|
A named director or proprietor must regularise before the entity can. | no |
| PV_DEDUCTIONS_UNTICKED | 409 |
Deductions not settled
Every deductible head must be marked withheld or settled before the net figure is released.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | yes |
| PV_TCC_STALE | 422 |
Tax clearance not current for payment
A current tax clearance certificate is required before this payment voucher can proceed.
|
The taxpayer must obtain or renew a tax clearance certificate. | no |
| QUEUED_DEGRADED | 202 |
Queued
The platform is in degraded mode; the request was queued and will be honoured when service resumes. No document may be issued meanwhile.
|
Transient. The identical call may succeed shortly. | yes |
| RATE_LIMITED | 429 |
Rate limited
Too many requests. Retry after {retry_after} seconds.
|
Transient. The identical call may succeed shortly. | yes |
| SANDBOX_ONLY | 403 |
Sandbox only
This endpoint is available to sandbox keys only.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| SCOPE_MISSING | 403 |
Scope missing
This key lacks the {scope} scope.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| SIGNATURE_INVALID | 401 |
Signature invalid
The request signature did not verify.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| SIGNATURE_SKEW | 401 |
Clock skew
The request timestamp is outside the accepted window. Server time: {server_time}.
|
Transient. The identical call may succeed shortly. | yes |
| STAMP_SHORTFALL | 422 |
Stamp duty shortfall
Stamp duty computed at {computed} exceeds the amount paid ({paid}). Balance {balance} is payable.
|
Money is owed; the link opens the bill. | no |
| STAMP_UNPAID | 422 |
Stamp duty unpaid
Stamp duty of {computed} is payable before this document can issue.
|
Money is owed; the link opens the bill. | no |
| TCC_EXPIRED | 422 |
Tax clearance certificate expired
The tax clearance certificate held by {party} expired on {expired_on}.
|
The taxpayer must obtain or renew a tax clearance certificate. | no |
| TCC_MISSING | 422 |
No tax clearance certificate
{party} holds no tax clearance certificate for {year}.
|
The taxpayer must obtain or renew a tax clearance certificate. | no |
| TCC_PENDING_VERIFICATION | 409 |
Tax clearance pending verification
A tax clearance application for {party} is still under review.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | yes |
| TCC_STALE_FOR_YEAR | 422 |
Tax clearance certificate not current for this year
A {tcc_year} certificate does not satisfy a transaction in {year}. A current certificate is required.
|
The taxpayer must obtain or renew a tax clearance certificate. | no |
| TLS_REQUIRED | 426 |
TLS required
The API is available over HTTPS only.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| VALIDATION_ERROR | 422 |
Validation error
The request is invalid: {field} - {problem}.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| VALUE_REQUIRED | 422 |
Declared value required
This process requires a declared transaction value.
|
Nothing the taxpayer can do from a link — fix the request, or the case needs an officer. | no |
| VALUE_VARIANCE | 422 |
Declared value above assessment basis
The declared value exceeds the basis of the tax clearance held; an additional assessment of {balance} has been raised.
|
Money is owed; the link opens the bill. | no |
Values in braces — {party}, {computed}, {director} — are filled from details before the message is sent, and also appear there as fields if you would rather compose your own sentence.
Failing well
- Never hide a refusal. The counter needs to see why, or the citizen is sent away without a reason and comes back angrier.
- Never invent a pass. If the platform is unreachable, queue the case; do not issue and reconcile later. The whole point of the gate is that nothing issues ahead of compliance.
- Keep the request id. X-Request-Id and verification_id are what BIR needs to tell you what happened.
- Retry only what says it is retryable, with the same Idempotency-Key and a widening delay.