Taxpayers
List Taxpayers
/v1/system-integrators/taxpayers
List taxpayers you've registered or synced with the FIRS system.
| Field | Type | Required | Description |
|---|---|---|---|
| search | string | No | Filter by name, TIN, or email |
| per_page | integer | No | Items per page (default: 15) |
{
"success": true,
"message": "Success",
"data": {
"data": [ { "...": "Taxpayer object — see Get Taxpayer" } ],
"current_page": 1,
"per_page": 15,
"total": 1,
"last_page": 1
}
}
Create Taxpayer
/v1/system-integrators/taxpayers
Register a new taxpayer to be synced or managed through the FIRS integration system. The taxpayer is automatically scoped to your System Integrator account.
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Registered business or taxpayer name |
| string | Yes | Taxpayer's business email address (must be unique) | |
| tin_no | string | Yes | Taxpayer Identification Number issued by FIRS (max 20 chars, must be unique) |
| phone | string | No | Taxpayer business phone number |
| nature_of_business | string | No | Brief description of the business activity (max 500 chars) |
| firs_service_id | string | Yes | FIRS service identifier — exactly 8 hexadecimal characters, must be unique |
| firs_business_id | string | Yes | FIRS business ID — must be a valid UUID, must be unique |
| address | string | Yes | Taxpayer business address |
| contact_person | object | Yes | first_name, last_name, email (all required); phone (optional); password (optional — see note below) |
email is the taxpayer's own business email, distinct from
contact_person.email (the contact person's email, used for their login account). If you omit
contact_person.password, the created contact account gets a system default password; pass your
own if you plan to let that contact log in directly.
{
"name": "Dangote Group",
"email": "info@dangote.com",
"tin_no": "TIN-000001",
"phone": "+23480254099000",
"address": "32 Owonikoko Street, Gwarinpa, Abuja",
"nature_of_business": "Cement and building materials supplier",
"firs_service_id": "94ND90NR",
"firs_business_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"contact_person": {
"first_name": "John",
"last_name": "Doe",
"email": "johndoe@gemspaysolution.com",
"phone": "+2348012345678"
}
}
{
"success": true,
"message": "Taxpayer created successfully",
"data": {
"id": 5,
"name": "Dangote Group",
"email": "info@dangote.com",
"tin_no": "TIN-000001",
"address": "32 Owonikoko Street, Gwarinpa, Abuja",
"nature_of_business": "Cement and building materials supplier",
"firs_business_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"firs_service_id": "94ND90NR",
"created_at": "2026-08-27T09:00:00.000000Z",
"updated_at": "2026-08-27T09:00:00.000000Z"
}
}
tin_no), which differs slightly from
Get Taxpayer's response shape (field name tin) below.
Get Taxpayer
/v1/system-integrators/taxpayers/{id}
Retrieve details of a specific taxpayer you own.
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer (path) | Yes | Taxpayer's portal ID |
{
"success": true,
"message": "Success",
"data": {
"id": 1,
"name": "Dangote Group",
"tin": "TIN-000001",
"email": "info@dangote.com",
"nature_of_business": "Cement and building materials supplier",
"firs_service_id": "94ND90NR",
"firs_business_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"address": "32 Owonikoko Street, Gwarinpa, Abuja",
"created_at": "2026-08-27 09:00:00",
"updated_at": "2026-08-27 09:00:00",
"users": [ { "...": "Contact person(s) attached to this taxpayer" } ]
}
}
Returns 404 with {"success": false, "message": "Taxpayer not found"} if the taxpayer
doesn't exist or belongs to a different System Integrator.
GET /v1/system-integrators/taxpayers/{id}/integration/setup is also available and currently
returns this same taxpayer object — it's not a separate ERP-configuration read. Use
Update Webhook to configure where this taxpayer's event notifications
are delivered.
Update Webhook
/v1/system-integrators/taxpayers/{id}/webhook
Set or update where a taxpayer's webhook notifications are delivered, and which events are sent.
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer (path) | Yes | Taxpayer's portal ID |
| webhook_url | string | Yes | A valid URL, max 500 characters |
| enabled_events | array | No | Event names to subscribe to — see the Webhooks page for the current catalog. Omit this key to leave existing events untouched; send an empty array to clear all events |
The first call for a taxpayer creates its integration record with sensible defaults (no auth, REST delivery) and activates it; a later call updates the URL/events without disturbing any ERP-specific auth/credentials configured elsewhere.
{
"webhook_url": "https://erp.example.com/webhooks/invoice",
"enabled_events": ["invoice.status-updated", "payment.status-updated"]
}
{
"success": true,
"message": "Webhook updated successfully",
"data": {
"id": 3,
"taxpayer_id": 1,
"webhook_url": "https://erp.example.com/webhooks/invoice",
"enabled_events": ["invoice.status-updated", "payment.status-updated"],
"is_active": true
}
}
Test Webhook
/v1/system-integrators/taxpayers/{id}/webhook/test
Send a test notification to a taxpayer's configured webhook URL, to confirm it's reachable before relying on real events.
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer (path) | Yes | Taxpayer's portal ID |
No request body. Returns 422 if the taxpayer has no webhook configured yet — call
Update Webhook first.
{
"success": true,
"message": "Connection test successful! Response code: 200",
"data": { "...": "Whatever your endpoint returned" }
}
Rotate Taxpayer API Key
/v1/system-integrators/taxpayers/{id}/api-key/rotate
Generate a new tpk_ API key for a taxpayer, invalidating their previous key.
| Field | Type | Required | Description |
|---|---|---|---|
| id | integer (path) | Yes | Taxpayer's portal ID |
No request body.
{
"success": true,
"message": "API key rotated successfully. Store this key now - it will not be shown again via this endpoint.",
"data": {
"taxpayer_id": 1,
"api_key": "tpk_9f2c1a8b7e4d6f0a2c5e8b1d4a7c0f3e"
}
}