Tax Verification (TIN)
Look up a Nigerian taxpayer record by tax number or phone number, check whether a TIN is valid, or find a person's TIN from their NIN.
Tax verification answers four questions about a Nigerian taxpayer, one endpoint each:
| Question | Endpoint | Returns |
|---|---|---|
| Who does this tax number belong to? | POST /v1/tin/verify | The full taxpayer record |
| Who does this phone number belong to? | POST /v1/tin/by-phone | The full taxpayer record |
| Is this tax number valid? | POST /v1/tin/validate | VALID or INVALID, and the registry it belongs to |
| What is this person's tax number? | POST /v1/tin/from-nin | Their TIN and basic identity fields |
Use it to onboard a business customer, confirm a supplier is tax-registered before raising a purchase order, or complete a taxpayer profile you already hold a NIN for.
There are two different Nigerian TIN formats, and they are not interchangeable
/tin/verify takes the FIRS form — 20304753-0001, eight digits, a hyphen, four digits.
/tin/validate takes the NRS form — bare digits, 10 to 13 of them, no hyphen.
These are two different identifiers issued by two different registries, not two spellings of
one number. Sending a FIRS number to /tin/validate will not resolve, and neither will the
reverse. If you only have one of them, use the endpoint that matches its shape.
Your first call
curl -X POST https://api.truztcube.com/v1/tin/verify \
-H "x-api-key: sk_live_your_key" \
-H "Idempotency-Key: supplier-onboarding-4821" \
-H "Content-Type: application/json" \
-d '{ "tin": "20304753-0001" }'{
"success": true,
"statusCode": 200,
"message": "TIN verification successful",
"data": {
"verificationStatus": "VERIFIED",
"referenceId": "VER-TIN_NG-JPGI3POERX",
"verificationId": "9f2c1a7b4e6d8f30",
"charged": true,
"taxpayer": {
"firsTin": "20304753-0001",
"jtbTin": "10001",
"taxpayerName": "ACME LIMITED",
"cacRegNumber": "2030404",
"taxOffice": "MSTO GARKI",
"phoneNumber": "08012345678",
"email": "accounts@acme.example",
"address": "13 Some Street, Garki"
}
},
"timestamp": "2026-09-02T14:12:19.911Z",
"path": "/v1/tin/verify"
}Endpoints
Taxpayer record
Two ways in, same record out. Both are covered by one subscription.
POST /v1/tin/verify
| Field | Required | Notes |
|---|---|---|
tin | yes | FIRS format — NNNNNNNN-NNNN, e.g. 20304753-0001 |
POST /v1/tin/by-phone
| Field | Required | Notes |
|---|---|---|
phoneNumber | yes | Nigerian mobile number, e.g. 08012345678 |
Both return a taxpayer object:
| Field | Notes |
|---|---|
firsTin | The FIRS tax number |
jtbTin | The NRS tax number for the same taxpayer, where the registry holds one |
taxpayerName | Registered name |
cacRegNumber | CAC registration number, for a registered company |
taxOffice | The tax office the taxpayer is administered by |
phoneNumber, email, address | Contact details as held by the registry |
Every field is nullable. The registry does not hold all of them for all taxpayers, and a missing field means the registry had nothing — not that the lookup failed.
jtbTin and firsTin come back together
A successful /tin/verify often returns both numbers for the same taxpayer. If you need the
NRS number and hold only the FIRS one, this is the cheaper path — one call rather than a
lookup followed by a validation.
Validate a tax number
POST /v1/tin/validate
| Field | Required | Notes |
|---|---|---|
tin | yes | NRS format — 10 to 13 bare digits, e.g. 1001180000 |
country | no | Two-letter country code. Defaults to ng |
{
"verificationStatus": "NOT_VERIFIED",
"result": "INVALID",
"format": null,
"tinType": null,
"country": "Nigeria (NG)",
"charged": true,
"verificationId": "…"
}| Field | Notes |
|---|---|
result | VALID or INVALID — this is the verdict |
format | The number as the registry recognises it |
tinType | Which registry issued it, e.g. NRS - Tax Identification Number (Tax ID) |
country | Resolved country |
An INVALID answer is still charged
result: "INVALID" is a successful verification: you asked the registry a question and it
answered. The call is billed, charged is true, and verificationStatus is
NOT_VERIFIED.
Retrying an INVALID will produce the same answer and a second charge. Treat it as a final
result, not a transient failure.
verificationStatus on this endpoint is derived from result, so the two always agree. Read
either — but read one of them, not the HTTP status. A 200 here means "the registry
answered", not "the TIN is good".
Find a TIN from a NIN
POST /v1/tin/from-nin
| Field | Required | Notes |
|---|---|---|
nin | yes | The person's 11-digit National Identification Number |
{
"verificationStatus": "VERIFIED",
"tin": "1234567890123",
"firstName": "Ada",
"lastName": "Okoro",
"dateOfBirth": "01/01/1990",
"nin": "12345678901",
"taxResidency": "Lagos State",
"charged": true,
"verificationId": "…"
}nin in the response echoes what you sent. taxResidency is the state the person is
registered to for tax purposes.
This endpoint returns personal data
Unlike the other three, this one resolves a person rather than a business. Their tax number is treated as the same class of identifier as a NIN or BVN — collect it under a lawful basis, store it as you would a NIN, and do not log it in plain text.
Headers
| Header | Required | Notes |
|---|---|---|
x-api-key | yes | Your API key |
Idempotency-Key | yes on live keys | Any unique string per logical request. Required for live-mode calls; optional in test mode |
Content-Type | yes | application/json |
Reusing an Idempotency-Key returns the original result without a second charge. Reusing one
with a different body is a 409.
Subscriptions
Tax verification is three separately provisioned services:
| Service | Grants |
|---|---|
| TIN Verification | /tin/verify and /tin/by-phone |
| TIN Validation | /tin/validate |
| TIN from NIN Verification | /tin/from-nin |
/tin/verify and /tin/by-phone share one subscription because they are the same registry
lookup with a different input. The other two return materially different things — a verdict,
and a person's tax number — so they are subscribed and priced on their own.
A call to an endpoint you are not subscribed to returns 403. Contact your account manager
to have a service enabled; pricing is set per organisation and is not published here.
Errors
| Status | Meaning | What to do |
|---|---|---|
400 | Malformed request — usually the wrong TIN format for the endpoint | Check the format table above |
402 | Insufficient wallet balance | Top up |
403 | Not subscribed to this service | Contact your account manager |
404 | No taxpayer record for this identifier | Final answer, not an error to retry |
409 | Idempotency-Key reused with a different body | Use a new key |
429 | Endpoint at capacity | Retry with backoff |
503 | Tax verification unavailable | Retry shortly; contact support if it persists |
A 404 and a result: "INVALID" are different answers to different questions. 404 means
the registry holds no record for that identifier. INVALID means the number itself is not a
well-formed, issued TIN.
See Errors for the shared error envelope.
Not yet available
Lookup by CAC registration number is built but not released. If you need to resolve a
taxpayer from an RC number today, use /v1/tin/verify with the FIRS TIN, or
Business Verification to confirm the company first.
Business Verification (CAC)
Confirm a Nigerian company exists with the Corporate Affairs Commission and return its registry record — company details on Basic, plus directors and shareholding on Advance.
Integration Methods
How to integrate Truztcube — the REST API today, with hosted flows, widgets and SDKs on the roadmap.