Batch VAT Filing
Authentication Required
This endpoint requires a valid API key in the x-api-key header of every request.
The Batch VAT Filing API processes multiple Value Added Tax transactions in a single request. Ideal for end-of-day reconciliation flows, bulk invoice uploads, or ERP integrations where many line items accumulate before submission.
Integration Flow
- 1Encrypt Credentials: Generate your
encryptedPayloadonce per request โ it covers all items in the batch. - 2Assemble the Batch: Collect all VAT line items into the
dataarray. - 3Handle Result: Listen for
vat.filing.successwebhooks โ one event is emitted per batch.
HTTP Request
Request Body
Top-level parameters for the batch request.
| Parameter | Type | Required | Description |
|---|---|---|---|
| batchId | string | Required | Unique idempotency key for this batch request. Prevents duplicate batch submissions. |
| payload | array | Required | Array of filing item objects to be processed in batch (see schema below). |
payload[ ] โ Batch Filing Item Schema
| Field | Type | Required | Description |
|---|---|---|---|
| encryptedPayload | string | Required | AES-256-GCM encrypted TaxPromax credentials. See Encryption Guide. |
| filingId | string | Required | Unique filing identifier / idempotency key for this item. |
| month | number | Required | Numeric month being filed (1โ12). |
| year | number | Required | 4-digit filing year (e.g. 2026). |
| vatAmount | number | Required | Total VAT amount to file. |
| taxId | string | Required | Tax Identification Number (TIN) for the business entity. |
| interestAmount | number | Required | Accrued interest amount if filing past statutory deadline. |
| penaltyAmount | number | Required | Late filing penalty amount if applicable. |
| scheduleUrl | string | One of | URL of a schedule workbook you built yourself (xlsx). Use this instead of sales / purchases for large entries. Send inline rows or scheduleUrl, not both. |
| sales | array | One of | Inline sales for the VAT return (max 500 rows) โ we place them on the NRS "A - Sales" schedule. See the sales[] item below. |
| purchases | array | One of | Inline purchases for the VAT return (max 500 rows) โ we place them on the NRS C_2 purchases list. See the purchases[] item below. |
Send the schedule in one of two ways. Either inline: sales and/or purchases (up to 500 rows each), from which we build the NRS VAT schedule workbook for you. Or as a workbook you built yourself, via scheduleUrl, which is the route for large entries. Sending inline rows together with scheduleUrl, or neither, returns 400 Bad Request. Send only purchases for a nil-sales return. When you send inline rows we build and upload the workbook before accepting the request, so the response can take around 20 seconds. A batch may carry inline rows for at most 10 filings; use scheduleUrl for the rest.
sales[] item
| Parameter | Type | Required | Description |
|---|---|---|---|
| customerName | string | Required | Name of the customer. |
| customerTaxId | string | Optional | Customer Tax ID. If omitted it is filed as 0. |
| item | string | Required | Product or service name. |
| description | string | Optional | Product or service description. |
| vatStatus | string | Required | VAT treatment: standard-rated, zero-rated or vat-exempt. |
| state | string | Optional | Place of consumption: a Nigerian state name, ISO code (e.g. NG-LA) or FCT. Defaults to Lagos. An unknown state returns 400. |
| lga | string | Optional | Place of consumption: Local Government Area. Left blank if omitted. |
| amountExclVat | number | Required | Sale amount excluding VAT, filed exactly as given. Must be 0 or more. |
purchases[] item
| Parameter | Type | Required | Description |
|---|---|---|---|
| sellerName | string | Required | Name of the supplier. |
| sellerTaxId | string | Optional | Supplier Tax ID. If omitted it is filed as 0. |
| description | string | Required | What was purchased. |
| amountExclVat | number | Required | Purchase amount excluding VAT. Must be 0 or more. |
| vatStatus | string | Required | VAT treatment: standard-rated, zero-rated or vat-exempt. |
| supplyType | string | Required | goods or service. Purchases without a supply type cannot be placed on the schedule. |
Encrypted Payload
FLUX requires sensitive credentials to be encrypted at the application layer. One encryptedPayload covers the entire batch.
The encryptedPayload must be a Base64-encoded AES-256-GCM encrypted JSON object containing your TaxPromax email and password.
Idempotency
The batchId you send is the idempotency key for this request. It lets you retry safely after a timeout or network error without filing, or being charged, twice. Keys are tracked per environment, so a sandbox request never collides with a production one.
| You send | You get |
|---|---|
A new batchId | The batch is accepted and charged as normal. |
The same batchId with the same payload | The original response again, with "replayed": true. Nothing is filed or charged a second time. |
The same batchId with a different payload | 409 Conflict. Use a new batchId for a different batch. |
The same batchId while the first request is still processing | 409 Conflict. Wait a moment and retry; you will then receive the replayed response. |
The same batchId after a failed request (400, 402, 403, 5xx) | Treated as a fresh request. A failed request releases the key, so you can fix the problem and retry with the same batchId. |
A replayed response looks like this:
{
"status": "accepted",
"message": "batch filing accepted successfully",
"data": { ... same as the original response ... },
"replayed": true
}The payload comparison ignores encryptedPayload, so re-encrypting the same filing for a retry is still a replay. Replays are remembered for 7 days.
Response
Returns 202 Accepted on success. Filing is processed asynchronously โ listen for the vat.filing.success webhook for the final outcome.
| HTTP Status | Error Key | Cause & Resolution |
|---|---|---|
| 400 | Bad Request | Missing or invalid fields. Check the errors array for field-level detail. |
| 401 | Unauthorized | Missing or invalid x-api-key header. |
| 402 | Payment Required | Your credit balance is too low for this request. Each filing costs 2 credits, and a balance of 4 or fewer is treated as empty. Top up your credits, then retry with the same batchId. |
| 403 | Forbidden | No active subscription for this service, or the API key belongs to a plan that does not include Flux. Sandbox keys (txsm_test_) are not affected. Subscribe to Flux, or use a key from a Flux plan. |
| 409 | Conflict | The batchId was already used with a different payload, or the first request with this batchId is still being processed. Use a new batchId for a different filing. If the first request is still processing, wait briefly and retry with the same payload to receive the replayed response. |
| 429 | Too Many Requests | Rate limit exceeded. Backoff using the Retry-After header. |
curl -X POST https://api.taxstreem.com/v1/flux/vat-filing/batch \ -H "x-api-key: txsm_test_SK489c..." \ -H "Content-Type: application/json" \ -d '{ "batchId": "batch_2343dfw", "payload": [ { "encryptedPayload": "aXZJVkpTT05...YWx1ZQ==", "filingId": "filing_2343dfw", "month": 1, "year": 2026, "vatAmount": 0, "taxId": "", "interestAmount": 0, "penaltyAmount": 0, "sales": [ { "customerName": "Shoprite Nigeria Ltd", "customerTaxId": "1234567890123", "item": "Consulting retainer", "description": "March retainer", "vatStatus": "standard-rated", "state": "Lagos", "lga": "Ikeja", "amountExclVat": 900000 } ], "purchases": [ { "sellerName": "Acme Consulting Ltd", "sellerTaxId": "1234567890123", "description": "Consulting, March", "amountExclVat": 250000, "vatStatus": "standard-rated", "supplyType": "service" } ] } ] }'
{
ย ย "status": "accepted",
ย ย "message": "schedule accepted successfully",
ย ย "data": {
ย ย ย ย "id": "xaee2ddf-batch-90",
ย ย ย ย "created_at": "2026-02-20T10:00:00Z"
ย ย }
}