Version 1.0.0
Droomwork REMIT AUTHORITY RAIL
Statutory remittance to Nigerian authorities, with proof of every payment.
https://sandbox.droomwork.ioDroomwork-Api-Key: dw_test_… or Authorization: Bearer dw_test_…REMIT files what your payroll says is owed with each authority and keeps the receipt for you.
What you should know before you start
You don't need RUN to use this. Send instruction sets from Droomwork payroll or from your own, by API or by file. The shape is the same either way, and so is everything that follows.
Intake is two steps. You submit, we validate and return a report, and nothing is committed until you accept. A discrepancy blocks acceptance until you resolve it or override it with a reason code. A figure filed wrongly is one you have to unwind with an authority.
One approval, many legs. A remittance executes one leg per authority, and each leg runs on its own. One authority being down never blocks the others, so a Federal Inland Revenue Service outage does not delay your pension filings.
A leg is complete when its receipt is vaulted. A receipt whose parsed amount, period or authority disagrees with the leg is quarantined, not accepted.
Every authority presents the same contract. Some file by direct API, some by portal automation, some by assisted manual filing. The request, the states, the webhooks and the evidence class are identical across all three. Tier is something you can read, never something you code against.
Getting started
Get a sandbox key from the developer portal. Submit an instruction set. Accept it. Create a remittance from it, approve it, then execute it.
Every operation below has two samples: Direct HTTP, with nothing but your language's own client, and Client library, with ours. Same request, same answer; the switch above each sample picks one and remembers it. Which should I use?
/v1/remittance/instruction_sets#List instruction sets
remittance.instruction_sets.list
Lists your instruction sets, newest first.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
status
string
optionalReturn only sets in this state: received on submission, validating while every line is checked, pending_acceptance once the report is back, accepted or rejected once you decide. Leave it out to get every state.
receivedvalidatingpending_acceptanceacceptedrejectedperiod
string
optionalReturn only sets for this month, as YYYY-MM, such as 2026-09. Leave it out to get every period.
Returns
A page of instruction sets.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of IngestedInstructionSet
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
13 fields of IngestedInstructionSet
id
string
requiredThe set's identifier, starting remit_authority_rail_instruction_, as listed at GET /v1/remittance/instruction_sets. It never changes; pass it as instruction_set_id to retrieve, accept, reject or remit the set.
object
always "ingested_instruction_set"
requiredAlways ingested_instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredNothing is committed until accepted.
receivedvalidatingpending_acceptanceacceptedrejectedsource
string
requiredWhere the set came from. Droomwork payroll or your own, by API or by file. Everything downstream behaves identically whichever it was.
runexternal_apiexternal_fileperiod
string
requiredThe month the set covers, as YYYY-MM, such as 2026-09. Filter the list by it with the period query.
run_id
string · nullable
optionalThe Droomwork payroll run the set came from, by its id from POST /v1/payroll/runs or GET /v1/payroll/runs, starting run_enterprise_. Present when source is run; null when the set came from your own payroll.
instructions
InstructionSet
optionalWhat is owed to whom for one run. This shape is owned jointly by RUN and REMIT. RUN row 19 emits it and REMIT row 1 ingests it, from RUN and from external payroll alike. It lives here rather than in either module document so the two cannot drift, which is the failure that would otherwise surface at M3 with RUN already accepted and paid. Totals reconcile to run totals to the kobo, because they sum payslip lines rather than recompute from an aggregate. This is the object REMIT ingests.
11 fields of InstructionSet
id
string
requiredThe instruction set's identifier, which never changes: read it at GET /v1/payroll/runs/{run_id}/instruction_set when Droomwork ran the payroll, and send the set on unchanged to POST /v1/remittance/instruction_sets. Quote it when you ask about the set.
object
always "instruction_set"
requiredAlways instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
run_id
string
requiredThe payroll run this set is owed for, by its id from POST /v1/payroll/runs, which starts with run_enterprise_. The set's totals reconcile to that run's totals to the kobo.
period
string
optionalThe pay period the amounts are owed for, as year and month, for example 2026-09.
paye
array of object
requiredGrouped by the State IRS of the employee's residence, not the employer's location.
5 fields
authority_id
string
requiredThe State Internal Revenue Service this PAYE is owed to, by its id from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. Use it wherever a call names the authority.
jurisdiction
string
requiredThe State Internal Revenue Service this line is grouped under, named in full, for example Rivers State Internal Revenue Service. Read it to label the line; authority_id names the authority in a call.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
payee_count
integer
optionalHow many employees this line's PAYE covers. Optional; when it is present, check it against your own headcount for that state.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it, for example paye-2026-09-rivers. Keep it with your own records so you can trace the line later.
pension
array of object
requiredGrouped by administrator and retirement savings account number.
6 fields
administrator_id
string
requiredThe Pension Fund Administrator these contributions are owed to, by its id from GET /v1/remittance/authorities with kind=pension_administrator, which starts with remit_authority_rail_obligation_. Use it wherever a call names the administrator.
administrator_name
string
optionalThe administrator's name in full, so you can label the line without a second call. Optional; administrator_id is what names the administrator in a call.
employee_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
employer_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it. Keep it with your own records so you can trace the line later.
levies
array of object
requiredNHF, NSITF, ITF and NHIA totals, each with a reconciliation reference.
3 fields
code
string
requiredWhich levy this line is for: nhf the National Housing Fund, nsitf the Nigeria Social Insurance Trust Fund, itf the Industrial Training Fund, nhia the National Health Insurance Authority. One line per levy.
nhfnsitfitfnhiaamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this levy line when you reconcile it. Keep it with your own records so you can trace the line later.
totals
object
requiredThe set's grand total, which its lines sum to. From a Droomwork run it reconciles to the run's totals to the kobo.
1 field
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
jurisdiction_pack
object
optionalThe jurisdiction pack the set is pinned to, by identifier and version. Every line was recomputed against it, so its rules are the ones the validation report reflects.
2 fields
pack_id
string
optionalWhich jurisdiction pack the set is pinned to, such as ng-paye. We publish the packs and you never send this; with version, it names exactly which rules every line was checked against, and it stays with the set so you can show which rules applied.
version
string
optionalThe pack version the set was checked against, such as 2026.08.1. It's pinned, so a later pack release doesn't change what this set was judged by.
accepted_by
string · nullable
optionalWho accepted the set: the actor that called accept. null until the set is accepted.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
const result = await api.remittanceInstructionSetsList({ limit: 25, status: 'received', period: '2026-09' });// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
result = api.remittance_instruction_sets_list(limit=25, status='received', period='2026-09')import os
import requests
# query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
$result = $api->remittanceInstructionSetsList(limit: 25, status: 'received', period: '2026-09');<?php
// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
import com.droomwork.sdk.model.*;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
var result = api.remittanceInstructionSetsList(25, null, RemitInstructionSetStatus.fromValue("received"), "2026-09");// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
var result = api.RemittanceInstructionSetsList(limit: 25, status: RemitInstructionSetStatus.Received, period: "2026-09");// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
result, _, err := client.REMITAPI.RemittanceInstructionSetsList(ctx).Limit(25).Status(droomwork.RemitInstructionSetStatus("received")).Period("2026-09").Execute()// query parameters: limit (optional), starting_after (optional), status (optional), period (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/instruction_sets?limit=25&status=received&period=2026-09", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "ingested_instruction_set",
"livemode": true,
"mocked": true,
"status": "received",
"source": "run",
"period": "2026-09",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"jurisdiction_pack": {
"pack_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"version": "2026.08.1"
},
"accepted_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
],
"has_more": true
}
/v1/remittance/instruction_sets#Submit an instruction set
remittance.instruction_sets.create
Send what your payroll says is owed, from Droomwork payroll or from your own system. We recompute every line against the jurisdiction pack the set is pinned to, and you get the result back as a validation report.
Nothing is committed here. The set sits in pending_acceptance until you accept it.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body
period
string
requiredThe month the figures cover, as YYYY-MM, such as 2026-09. What you owe for it is recorded against this period once you accept.
run_id
string
optionalThe Droomwork payroll run these figures come from, by its id from POST /v1/payroll/runs or GET /v1/payroll/runs, starting run_enterprise_. Omit it when the set comes from your own payroll system.
instructions
InstructionSet
requiredWhat is owed to whom for one run. This shape is owned jointly by RUN and REMIT. RUN row 19 emits it and REMIT row 1 ingests it, from RUN and from external payroll alike. It lives here rather than in either module document so the two cannot drift, which is the failure that would otherwise surface at M3 with RUN already accepted and paid. Totals reconcile to run totals to the kobo, because they sum payslip lines rather than recompute from an aggregate. This is the object REMIT ingests.
11 fields of InstructionSet
id
string
requiredThe instruction set's identifier, which never changes: read it at GET /v1/payroll/runs/{run_id}/instruction_set when Droomwork ran the payroll, and send the set on unchanged to POST /v1/remittance/instruction_sets. Quote it when you ask about the set.
object
always "instruction_set"
requiredAlways instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
run_id
string
requiredThe payroll run this set is owed for, by its id from POST /v1/payroll/runs, which starts with run_enterprise_. The set's totals reconcile to that run's totals to the kobo.
period
string
optionalThe pay period the amounts are owed for, as year and month, for example 2026-09.
paye
array of object
requiredGrouped by the State IRS of the employee's residence, not the employer's location.
5 fields
authority_id
string
requiredThe State Internal Revenue Service this PAYE is owed to, by its id from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. Use it wherever a call names the authority.
jurisdiction
string
requiredThe State Internal Revenue Service this line is grouped under, named in full, for example Rivers State Internal Revenue Service. Read it to label the line; authority_id names the authority in a call.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
payee_count
integer
optionalHow many employees this line's PAYE covers. Optional; when it is present, check it against your own headcount for that state.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it, for example paye-2026-09-rivers. Keep it with your own records so you can trace the line later.
pension
array of object
requiredGrouped by administrator and retirement savings account number.
6 fields
administrator_id
string
requiredThe Pension Fund Administrator these contributions are owed to, by its id from GET /v1/remittance/authorities with kind=pension_administrator, which starts with remit_authority_rail_obligation_. Use it wherever a call names the administrator.
administrator_name
string
optionalThe administrator's name in full, so you can label the line without a second call. Optional; administrator_id is what names the administrator in a call.
employee_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
employer_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it. Keep it with your own records so you can trace the line later.
levies
array of object
requiredNHF, NSITF, ITF and NHIA totals, each with a reconciliation reference.
3 fields
code
string
requiredWhich levy this line is for: nhf the National Housing Fund, nsitf the Nigeria Social Insurance Trust Fund, itf the Industrial Training Fund, nhia the National Health Insurance Authority. One line per levy.
nhfnsitfitfnhiaamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this levy line when you reconcile it. Keep it with your own records so you can trace the line later.
totals
object
requiredThe set's grand total, which its lines sum to. From a Droomwork run it reconciles to the run's totals to the kobo.
1 field
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Returns
The ingested set, with its validation report.
id
string
requiredThe set's identifier, starting remit_authority_rail_instruction_, as listed at GET /v1/remittance/instruction_sets. It never changes; pass it as instruction_set_id to retrieve, accept, reject or remit the set.
object
always "ingested_instruction_set"
requiredAlways ingested_instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredNothing is committed until accepted.
receivedvalidatingpending_acceptanceacceptedrejectedsource
string
requiredWhere the set came from. Droomwork payroll or your own, by API or by file. Everything downstream behaves identically whichever it was.
runexternal_apiexternal_fileperiod
string
requiredThe month the set covers, as YYYY-MM, such as 2026-09. Filter the list by it with the period query.
run_id
string · nullable
optionalThe Droomwork payroll run the set came from, by its id from POST /v1/payroll/runs or GET /v1/payroll/runs, starting run_enterprise_. Present when source is run; null when the set came from your own payroll.
instructions
InstructionSet
optionalWhat is owed to whom for one run. This shape is owned jointly by RUN and REMIT. RUN row 19 emits it and REMIT row 1 ingests it, from RUN and from external payroll alike. It lives here rather than in either module document so the two cannot drift, which is the failure that would otherwise surface at M3 with RUN already accepted and paid. Totals reconcile to run totals to the kobo, because they sum payslip lines rather than recompute from an aggregate. This is the object REMIT ingests.
11 fields of InstructionSet
id
string
requiredThe instruction set's identifier, which never changes: read it at GET /v1/payroll/runs/{run_id}/instruction_set when Droomwork ran the payroll, and send the set on unchanged to POST /v1/remittance/instruction_sets. Quote it when you ask about the set.
object
always "instruction_set"
requiredAlways instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
run_id
string
requiredThe payroll run this set is owed for, by its id from POST /v1/payroll/runs, which starts with run_enterprise_. The set's totals reconcile to that run's totals to the kobo.
period
string
optionalThe pay period the amounts are owed for, as year and month, for example 2026-09.
paye
array of object
requiredGrouped by the State IRS of the employee's residence, not the employer's location.
5 fields
authority_id
string
requiredThe State Internal Revenue Service this PAYE is owed to, by its id from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. Use it wherever a call names the authority.
jurisdiction
string
requiredThe State Internal Revenue Service this line is grouped under, named in full, for example Rivers State Internal Revenue Service. Read it to label the line; authority_id names the authority in a call.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
payee_count
integer
optionalHow many employees this line's PAYE covers. Optional; when it is present, check it against your own headcount for that state.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it, for example paye-2026-09-rivers. Keep it with your own records so you can trace the line later.
pension
array of object
requiredGrouped by administrator and retirement savings account number.
6 fields
administrator_id
string
requiredThe Pension Fund Administrator these contributions are owed to, by its id from GET /v1/remittance/authorities with kind=pension_administrator, which starts with remit_authority_rail_obligation_. Use it wherever a call names the administrator.
administrator_name
string
optionalThe administrator's name in full, so you can label the line without a second call. Optional; administrator_id is what names the administrator in a call.
employee_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
employer_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it. Keep it with your own records so you can trace the line later.
levies
array of object
requiredNHF, NSITF, ITF and NHIA totals, each with a reconciliation reference.
3 fields
code
string
requiredWhich levy this line is for: nhf the National Housing Fund, nsitf the Nigeria Social Insurance Trust Fund, itf the Industrial Training Fund, nhia the National Health Insurance Authority. One line per levy.
nhfnsitfitfnhiaamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this levy line when you reconcile it. Keep it with your own records so you can trace the line later.
totals
object
requiredThe set's grand total, which its lines sum to. From a Droomwork run it reconciles to the run's totals to the kobo.
1 field
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
jurisdiction_pack
object
optionalThe jurisdiction pack the set is pinned to, by identifier and version. Every line was recomputed against it, so its rules are the ones the validation report reflects.
2 fields
pack_id
string
optionalWhich jurisdiction pack the set is pinned to, such as ng-paye. We publish the packs and you never send this; with version, it names exactly which rules every line was checked against, and it stays with the set so you can show which rules applied.
version
string
optionalThe pack version the set was checked against, such as 2026.08.1. It's pinned, so a later pack release doesn't change what this set was judged by.
accepted_by
string · nullable
optionalWho accepted the set: the actor that called accept. null until the set is accepted.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/instruction_sets" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"period":"2026-09","instructions":{"id":"remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","object":"instruction_set","livemode":true,"mocked":true,"run_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","paye":[{"authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","jurisdiction":"Rivers State Internal Revenue Service","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers","payee_count":1}],"pension":[{"administrator_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers","administrator_name":"Rivers State Internal Revenue Service","employee_amount":{"amount":1234567,"currency":"NGN"},"employer_amount":{"amount":1234567,"currency":"NGN"}}],"levies":[{"code":"nhf","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers"}],"totals":{"total":{"amount":1234567,"currency":"NGN"}},"period":"2026-09","created_at":"2026-09-01T09:00:00Z"},"run_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceInstructionSetsCreate({
idempotencyKey: crypto.randomUUID(),
remitInstructionSetCreateRequest: {"period":"2026-09","instructions":{"id":"remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","object":"instruction_set","livemode":true,"mocked":true,"runId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","paye":[{"authorityId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","jurisdiction":"Rivers State Internal Revenue Service","amount":{"amount":1234567,"currency":"NGN"},"reconciliationReference":"paye-2026-09-rivers","payeeCount":1}],"pension":[{"administratorId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","amount":{"amount":1234567,"currency":"NGN"},"reconciliationReference":"paye-2026-09-rivers","administratorName":"Rivers State Internal Revenue Service","employeeAmount":{"amount":1234567,"currency":"NGN"},"employerAmount":{"amount":1234567,"currency":"NGN"}}],"levies":[{"code":"nhf","amount":{"amount":1234567,"currency":"NGN"},"reconciliationReference":"paye-2026-09-rivers"}],"totals":{"total":{"amount":1234567,"currency":"NGN"}},"period":"2026-09","createdAt":"2026-09-01T09:00:00Z"},"runId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"},
});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"period": "2026-09",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_instruction_sets_create(body={"period": "2026-09", "instructions": {"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "object": "instruction_set", "livemode": True, "mocked": True, "run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "paye": [{"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "jurisdiction": "Rivers State Internal Revenue Service", "amount": {"amount": 1234567, "currency": "NGN"}, "reconciliation_reference": "paye-2026-09-rivers", "payee_count": 1}], "pension": [{"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "amount": {"amount": 1234567, "currency": "NGN"}, "reconciliation_reference": "paye-2026-09-rivers", "administrator_name": "Rivers State Internal Revenue Service", "employee_amount": {"amount": 1234567, "currency": "NGN"}, "employer_amount": {"amount": 1234567, "currency": "NGN"}}], "levies": [{"code": "nhf", "amount": {"amount": 1234567, "currency": "NGN"}, "reconciliation_reference": "paye-2026-09-rivers"}], "totals": {"total": {"amount": 1234567, "currency": "NGN"}}, "period": "2026-09", "created_at": "2026-09-01T09:00:00Z"}, "run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"})import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"period": "2026-09", "instructions": {"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "object": "instruction_set", "livemode": True, "mocked": True, "run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "paye": [{"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "jurisdiction": "Rivers State Internal Revenue Service", "amount": {"amount": 1234567, "currency": "NGN"}, "reconciliation_reference": "paye-2026-09-rivers", "payee_count": 1}], "pension": [{"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "amount": {"amount": 1234567, "currency": "NGN"}, "reconciliation_reference": "paye-2026-09-rivers", "administrator_name": "Rivers State Internal Revenue Service", "employee_amount": {"amount": 1234567, "currency": "NGN"}, "employer_amount": {"amount": 1234567, "currency": "NGN"}}], "levies": [{"code": "nhf", "amount": {"amount": 1234567, "currency": "NGN"}, "reconciliation_reference": "paye-2026-09-rivers"}], "totals": {"total": {"amount": 1234567, "currency": "NGN"}}, "period": "2026-09", "created_at": "2026-09-01T09:00:00Z"}, "run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceInstructionSetsCreate($idempotencyKey, json_decode('{"period":"2026-09","instructions":{"id":"remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","object":"instruction_set","livemode":true,"mocked":true,"run_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","paye":[{"authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","jurisdiction":"Rivers State Internal Revenue Service","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers","payee_count":1}],"pension":[{"administrator_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers","administrator_name":"Rivers State Internal Revenue Service","employee_amount":{"amount":1234567,"currency":"NGN"},"employer_amount":{"amount":1234567,"currency":"NGN"}}],"levies":[{"code":"nhf","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers"}],"totals":{"total":{"amount":1234567,"currency":"NGN"}},"period":"2026-09","created_at":"2026-09-01T09:00:00Z"},"run_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"}', true));<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"period":"2026-09","instructions":{"id":"remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","object":"instruction_set","livemode":true,"mocked":true,"run_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","paye":[{"authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","jurisdiction":"Rivers State Internal Revenue Service","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers","payee_count":1}],"pension":[{"administrator_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers","administrator_name":"Rivers State Internal Revenue Service","employee_amount":{"amount":1234567,"currency":"NGN"},"employer_amount":{"amount":1234567,"currency":"NGN"}}],"levies":[{"code":"nhf","amount":{"amount":1234567,"currency":"NGN"},"reconciliation_reference":"paye-2026-09-rivers"}],"totals":{"total":{"amount":1234567,"currency":"NGN"}},"period":"2026-09","created_at":"2026-09-01T09:00:00Z"},"run_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceInstructionSetsCreate(idempotencyKey, body);var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"period": "2026-09",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceInstructionSetsCreate(idempotencyKey, body);using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/instruction_sets");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"period": "2026-09",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceInstructionSetsCreate(ctx).IdempotencyKey(key).RemitInstructionSetCreateRequest(body).Execute()body := strings.NewReader(`{
"period": "2026-09",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/instruction_sets", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "ingested_instruction_set",
"livemode": true,
"mocked": true,
"status": "received",
"source": "run",
"period": "2026-09",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"jurisdiction_pack": {
"pack_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"version": "2026.08.1"
},
"accepted_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/instruction_sets/{instruction_set_id}#Retrieve an instruction set
remittance.instruction_sets.retrieve
You get the set with its validation report and any open discrepancies.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
Returns
The instruction set.
id
string
requiredThe set's identifier, starting remit_authority_rail_instruction_, as listed at GET /v1/remittance/instruction_sets. It never changes; pass it as instruction_set_id to retrieve, accept, reject or remit the set.
object
always "ingested_instruction_set"
requiredAlways ingested_instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredNothing is committed until accepted.
receivedvalidatingpending_acceptanceacceptedrejectedsource
string
requiredWhere the set came from. Droomwork payroll or your own, by API or by file. Everything downstream behaves identically whichever it was.
runexternal_apiexternal_fileperiod
string
requiredThe month the set covers, as YYYY-MM, such as 2026-09. Filter the list by it with the period query.
run_id
string · nullable
optionalThe Droomwork payroll run the set came from, by its id from POST /v1/payroll/runs or GET /v1/payroll/runs, starting run_enterprise_. Present when source is run; null when the set came from your own payroll.
instructions
InstructionSet
optionalWhat is owed to whom for one run. This shape is owned jointly by RUN and REMIT. RUN row 19 emits it and REMIT row 1 ingests it, from RUN and from external payroll alike. It lives here rather than in either module document so the two cannot drift, which is the failure that would otherwise surface at M3 with RUN already accepted and paid. Totals reconcile to run totals to the kobo, because they sum payslip lines rather than recompute from an aggregate. This is the object REMIT ingests.
11 fields of InstructionSet
id
string
requiredThe instruction set's identifier, which never changes: read it at GET /v1/payroll/runs/{run_id}/instruction_set when Droomwork ran the payroll, and send the set on unchanged to POST /v1/remittance/instruction_sets. Quote it when you ask about the set.
object
always "instruction_set"
requiredAlways instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
run_id
string
requiredThe payroll run this set is owed for, by its id from POST /v1/payroll/runs, which starts with run_enterprise_. The set's totals reconcile to that run's totals to the kobo.
period
string
optionalThe pay period the amounts are owed for, as year and month, for example 2026-09.
paye
array of object
requiredGrouped by the State IRS of the employee's residence, not the employer's location.
5 fields
authority_id
string
requiredThe State Internal Revenue Service this PAYE is owed to, by its id from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. Use it wherever a call names the authority.
jurisdiction
string
requiredThe State Internal Revenue Service this line is grouped under, named in full, for example Rivers State Internal Revenue Service. Read it to label the line; authority_id names the authority in a call.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
payee_count
integer
optionalHow many employees this line's PAYE covers. Optional; when it is present, check it against your own headcount for that state.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it, for example paye-2026-09-rivers. Keep it with your own records so you can trace the line later.
pension
array of object
requiredGrouped by administrator and retirement savings account number.
6 fields
administrator_id
string
requiredThe Pension Fund Administrator these contributions are owed to, by its id from GET /v1/remittance/authorities with kind=pension_administrator, which starts with remit_authority_rail_obligation_. Use it wherever a call names the administrator.
administrator_name
string
optionalThe administrator's name in full, so you can label the line without a second call. Optional; administrator_id is what names the administrator in a call.
employee_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
employer_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it. Keep it with your own records so you can trace the line later.
levies
array of object
requiredNHF, NSITF, ITF and NHIA totals, each with a reconciliation reference.
3 fields
code
string
requiredWhich levy this line is for: nhf the National Housing Fund, nsitf the Nigeria Social Insurance Trust Fund, itf the Industrial Training Fund, nhia the National Health Insurance Authority. One line per levy.
nhfnsitfitfnhiaamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this levy line when you reconcile it. Keep it with your own records so you can trace the line later.
totals
object
requiredThe set's grand total, which its lines sum to. From a Droomwork run it reconciles to the run's totals to the kobo.
1 field
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
jurisdiction_pack
object
optionalThe jurisdiction pack the set is pinned to, by identifier and version. Every line was recomputed against it, so its rules are the ones the validation report reflects.
2 fields
pack_id
string
optionalWhich jurisdiction pack the set is pinned to, such as ng-paye. We publish the packs and you never send this; with version, it names exactly which rules every line was checked against, and it stays with the set so you can show which rules applied.
version
string
optionalThe pack version the set was checked against, such as 2026.08.1. It's pinned, so a later pack release doesn't change what this set was judged by.
accepted_by
string · nullable
optionalWho accepted the set: the actor that called accept. null until the set is accepted.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceInstructionSetsRetrieve({ instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_instruction_sets_retrieve(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceInstructionSetsRetrieve(instruction_set_id: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceInstructionSetsRetrieve("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceInstructionSetsRetrieve(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceInstructionSetsRetrieve(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "ingested_instruction_set",
"livemode": true,
"mocked": true,
"status": "received",
"source": "run",
"period": "2026-09",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"jurisdiction_pack": {
"pack_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"version": "2026.08.1"
},
"accepted_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/instruction_sets/{instruction_set_id}/accept#Accept an instruction set for remittance
remittance.instruction_sets.accept
Refused while any discrepancy is open. Resolve each one first, or override it with a reason code.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
The accepted set.
id
string
requiredThe set's identifier, starting remit_authority_rail_instruction_, as listed at GET /v1/remittance/instruction_sets. It never changes; pass it as instruction_set_id to retrieve, accept, reject or remit the set.
object
always "ingested_instruction_set"
requiredAlways ingested_instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredNothing is committed until accepted.
receivedvalidatingpending_acceptanceacceptedrejectedsource
string
requiredWhere the set came from. Droomwork payroll or your own, by API or by file. Everything downstream behaves identically whichever it was.
runexternal_apiexternal_fileperiod
string
requiredThe month the set covers, as YYYY-MM, such as 2026-09. Filter the list by it with the period query.
run_id
string · nullable
optionalThe Droomwork payroll run the set came from, by its id from POST /v1/payroll/runs or GET /v1/payroll/runs, starting run_enterprise_. Present when source is run; null when the set came from your own payroll.
instructions
InstructionSet
optionalWhat is owed to whom for one run. This shape is owned jointly by RUN and REMIT. RUN row 19 emits it and REMIT row 1 ingests it, from RUN and from external payroll alike. It lives here rather than in either module document so the two cannot drift, which is the failure that would otherwise surface at M3 with RUN already accepted and paid. Totals reconcile to run totals to the kobo, because they sum payslip lines rather than recompute from an aggregate. This is the object REMIT ingests.
11 fields of InstructionSet
id
string
requiredThe instruction set's identifier, which never changes: read it at GET /v1/payroll/runs/{run_id}/instruction_set when Droomwork ran the payroll, and send the set on unchanged to POST /v1/remittance/instruction_sets. Quote it when you ask about the set.
object
always "instruction_set"
requiredAlways instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
run_id
string
requiredThe payroll run this set is owed for, by its id from POST /v1/payroll/runs, which starts with run_enterprise_. The set's totals reconcile to that run's totals to the kobo.
period
string
optionalThe pay period the amounts are owed for, as year and month, for example 2026-09.
paye
array of object
requiredGrouped by the State IRS of the employee's residence, not the employer's location.
5 fields
authority_id
string
requiredThe State Internal Revenue Service this PAYE is owed to, by its id from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. Use it wherever a call names the authority.
jurisdiction
string
requiredThe State Internal Revenue Service this line is grouped under, named in full, for example Rivers State Internal Revenue Service. Read it to label the line; authority_id names the authority in a call.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
payee_count
integer
optionalHow many employees this line's PAYE covers. Optional; when it is present, check it against your own headcount for that state.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it, for example paye-2026-09-rivers. Keep it with your own records so you can trace the line later.
pension
array of object
requiredGrouped by administrator and retirement savings account number.
6 fields
administrator_id
string
requiredThe Pension Fund Administrator these contributions are owed to, by its id from GET /v1/remittance/authorities with kind=pension_administrator, which starts with remit_authority_rail_obligation_. Use it wherever a call names the administrator.
administrator_name
string
optionalThe administrator's name in full, so you can label the line without a second call. Optional; administrator_id is what names the administrator in a call.
employee_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
employer_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it. Keep it with your own records so you can trace the line later.
levies
array of object
requiredNHF, NSITF, ITF and NHIA totals, each with a reconciliation reference.
3 fields
code
string
requiredWhich levy this line is for: nhf the National Housing Fund, nsitf the Nigeria Social Insurance Trust Fund, itf the Industrial Training Fund, nhia the National Health Insurance Authority. One line per levy.
nhfnsitfitfnhiaamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this levy line when you reconcile it. Keep it with your own records so you can trace the line later.
totals
object
requiredThe set's grand total, which its lines sum to. From a Droomwork run it reconciles to the run's totals to the kobo.
1 field
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
jurisdiction_pack
object
optionalThe jurisdiction pack the set is pinned to, by identifier and version. Every line was recomputed against it, so its rules are the ones the validation report reflects.
2 fields
pack_id
string
optionalWhich jurisdiction pack the set is pinned to, such as ng-paye. We publish the packs and you never send this; with version, it names exactly which rules every line was checked against, and it stays with the set so you can show which rules applied.
version
string
optionalThe pack version the set was checked against, such as 2026.08.1. It's pinned, so a later pack release doesn't change what this set was judged by.
accepted_by
string · nullable
optionalWho accepted the set: the actor that called accept. null until the set is accepted.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceInstructionSetsAccept({ instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_instruction_sets_accept(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceInstructionSetsAccept(instruction_set_id: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceInstructionSetsAccept("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceInstructionSetsAccept(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceInstructionSetsAccept(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/accept", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "ingested_instruction_set",
"livemode": true,
"mocked": true,
"status": "received",
"source": "run",
"period": "2026-09",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"jurisdiction_pack": {
"pack_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"version": "2026.08.1"
},
"accepted_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/instruction_sets/{instruction_set_id}/totals#Retrieve instruction set totals
remittance.instruction_sets.retrieve_totals
You get the totals by authority and whether they reconcile to the originating run. They reconcile to the kobo.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
Returns
The totals, with the reconciliation result.
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
by_authority
array of object
optionalOne entry per authority the set pays, with the authority's identifier and the amount owed to it, in whole minor units.
2 fields
authority_id
string
requiredThe authority this amount is owed to, by its id as listed at GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciles_to_run
boolean
requiredTrue when the totals match the originating run to the kobo. Absent a run, this reports whether the lines sum to the stated total.
difference
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceInstructionSetsRetrieveTotals({ instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_instruction_sets_retrieve_totals(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceInstructionSetsRetrieveTotals(instruction_set_id: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceInstructionSetsRetrieveTotals("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceInstructionSetsRetrieveTotals(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceInstructionSetsRetrieveTotals(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/totals", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"total": {
"amount": 1234567,
"currency": "NGN"
},
"reconciles_to_run": true,
"by_authority": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"difference": {
"amount": 1234567,
"currency": "NGN"
}
}
/v1/remittance/instruction_sets/{instruction_set_id}/discrepancies#List discrepancies on an instruction set
remittance.discrepancies.list
Lists what's blocking acceptance. A discrepancy is raised where a recomputed line disagrees with what you submitted, and where a residency conflict means PAYE would go to the wrong State Internal Revenue Service.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
Returns
A page of discrepancies.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Discrepancy
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
11 fields of Discrepancy
id
string
requiredThe discrepancy's identifier, as listed at GET /v1/remittance/instruction_sets/{instruction_set_id}/discrepancies. It never changes; pass it as discrepancy_id when you retrieve or override the discrepancy.
object
always "discrepancy"
requiredAlways discrepancy. Tells you which kind of record you are looking at, so one handler can read any response.
kind
string
requiredrecomputation_mismatchresidency_conflictmissing_identifierunknown_authoritystatus
string
requiredopen while it blocks acceptance, resolved once it's cleared, overridden once you've kept your submitted figure with a reason code at remittance.discrepancies.override. Acceptance needs none left open.
openresolvedoverriddenline
integer
optionalWhich line of the instruction set the discrepancy is on, counting from 1. Absent when it isn't tied to one line.
subject_id
string · nullable
optionalThe person the discrepancy is about, by the subject_id starting sub_ that's on their payslip at GET /v1/payroll/payslips: for example the employee whose residence puts their PAYE with another State IRS. null otherwise.
submitted
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
recomputed
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
difference
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reason_code
string · nullable
optionalThe reason code you gave when you overrode the discrepancy, kept on the record permanently. null until it is overridden.
overridden_by
string · nullable
optionalWho overrode the discrepancy: the actor that supplied the reason code, recorded permanently. null until it is overridden.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional)
const result = await api.remittanceDiscrepanciesList({ instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', limit: 25 });// query parameters: limit (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional)
result = api.remittance_discrepancies_list(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', limit=25)import os
import requests
# query parameters: limit (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional)
$result = $api->remittanceDiscrepanciesList(instruction_set_id: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', limit: 25);<?php
// query parameters: limit (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional)
var result = api.remittanceDiscrepanciesList("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", 25);// query parameters: limit (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional)
var result = api.RemittanceDiscrepanciesList(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", limit: 25);// query parameters: limit (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional)
result, _, err := client.REMITAPI.RemittanceDiscrepanciesList(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Limit(25).Execute()// query parameters: limit (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies?limit=25", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "discrepancy",
"kind": "recomputation_mismatch",
"status": "open",
"submitted": {
"amount": 1234567,
"currency": "NGN"
},
"recomputed": {
"amount": 1234567,
"currency": "NGN"
},
"line": 1,
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"difference": {
"amount": 1234567,
"currency": "NGN"
},
"reason_code": "no_payee_destination",
"overridden_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
],
"has_more": true
}
/v1/remittance/instruction_sets/{instruction_set_id}/discrepancies/{discrepancy_id}#Retrieve a discrepancy
remittance.discrepancies.retrieve
You get the figure you submitted, the figure we recomputed and the difference.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
discrepancy_id
string
requiredThe discrepancy's identifier, from the id of a discrepancy listed at GET /v1/remittance/instruction_sets/{instruction_set_id}/discrepancies. It belongs to the set in the path.
Returns
The discrepancy.
id
string
requiredThe discrepancy's identifier, as listed at GET /v1/remittance/instruction_sets/{instruction_set_id}/discrepancies. It never changes; pass it as discrepancy_id when you retrieve or override the discrepancy.
object
always "discrepancy"
requiredAlways discrepancy. Tells you which kind of record you are looking at, so one handler can read any response.
kind
string
requiredrecomputation_mismatchresidency_conflictmissing_identifierunknown_authoritystatus
string
requiredopen while it blocks acceptance, resolved once it's cleared, overridden once you've kept your submitted figure with a reason code at remittance.discrepancies.override. Acceptance needs none left open.
openresolvedoverriddenline
integer
optionalWhich line of the instruction set the discrepancy is on, counting from 1. Absent when it isn't tied to one line.
subject_id
string · nullable
optionalThe person the discrepancy is about, by the subject_id starting sub_ that's on their payslip at GET /v1/payroll/payslips: for example the employee whose residence puts their PAYE with another State IRS. null otherwise.
submitted
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
recomputed
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
difference
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reason_code
string · nullable
optionalThe reason code you gave when you overrode the discrepancy, kept on the record permanently. null until it is overridden.
overridden_by
string · nullable
optionalWho overrode the discrepancy: the actor that supplied the reason code, recorded permanently. null until it is overridden.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceDiscrepanciesRetrieve({ instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', discrepancyId: '{discrepancy_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_discrepancies_retrieve(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', discrepancy_id='{discrepancy_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceDiscrepanciesRetrieve(instruction_set_id: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', discrepancy_id: '{discrepancy_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceDiscrepanciesRetrieve("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{discrepancy_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceDiscrepanciesRetrieve(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", discrepancyId: "{discrepancy_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceDiscrepanciesRetrieve(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{discrepancy_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "discrepancy",
"kind": "recomputation_mismatch",
"status": "open",
"submitted": {
"amount": 1234567,
"currency": "NGN"
},
"recomputed": {
"amount": 1234567,
"currency": "NGN"
},
"line": 1,
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"difference": {
"amount": 1234567,
"currency": "NGN"
},
"reason_code": "no_payee_destination",
"overridden_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
/v1/remittance/instruction_sets/{instruction_set_id}/discrepancies/{discrepancy_id}/override#Override a discrepancy with a reason
remittance.discrepancies.override
Keep your submitted figure over the recomputed one. Send a reason code. It is recorded permanently with who supplied it, so a year from now you can show who decided and why.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
discrepancy_id
string
requiredThe discrepancy's identifier, from the id of a discrepancy listed at GET /v1/remittance/instruction_sets/{instruction_set_id}/discrepancies. It belongs to the set in the path.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body
reason_code
string
requiredRecorded permanently with the actor who supplied it.
note
string
optionalAnything a reviewer should know beyond the code, in your words. Optional; it goes on the record with the reason code.
Returns
The overridden discrepancy.
id
string
requiredThe discrepancy's identifier, as listed at GET /v1/remittance/instruction_sets/{instruction_set_id}/discrepancies. It never changes; pass it as discrepancy_id when you retrieve or override the discrepancy.
object
always "discrepancy"
requiredAlways discrepancy. Tells you which kind of record you are looking at, so one handler can read any response.
kind
string
requiredrecomputation_mismatchresidency_conflictmissing_identifierunknown_authoritystatus
string
requiredopen while it blocks acceptance, resolved once it's cleared, overridden once you've kept your submitted figure with a reason code at remittance.discrepancies.override. Acceptance needs none left open.
openresolvedoverriddenline
integer
optionalWhich line of the instruction set the discrepancy is on, counting from 1. Absent when it isn't tied to one line.
subject_id
string · nullable
optionalThe person the discrepancy is about, by the subject_id starting sub_ that's on their payslip at GET /v1/payroll/payslips: for example the employee whose residence puts their PAYE with another State IRS. null otherwise.
submitted
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
recomputed
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
difference
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reason_code
string · nullable
optionalThe reason code you gave when you overrode the discrepancy, kept on the record permanently. null until it is overridden.
overridden_by
string · nullable
optionalWho overrode the discrepancy: the actor that supplied the reason code, recorded permanently. null until it is overridden.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"reason_code":"no_payee_destination","note":"example"}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceDiscrepanciesOverride({
instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
discrepancyId: '{discrepancy_id}',
idempotencyKey: crypto.randomUUID(),
remitDiscrepancyOverrideRequest: {"reasonCode":"no_payee_destination","note":"example"},
});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"reason_code": "no_payee_destination",
"note": "example"
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_discrepancies_override(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', discrepancy_id='{discrepancy_id}', body={"reason_code": "no_payee_destination", "note": "example"})import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"reason_code": "no_payee_destination", "note": "example"},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceDiscrepanciesOverride($idempotencyKey, json_decode('{"reason_code":"no_payee_destination","note":"example"}', true));<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"reason_code":"no_payee_destination","note":"example"}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceDiscrepanciesOverride("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{discrepancy_id}", idempotencyKey, body);var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"reason_code": "no_payee_destination",
"note": "example"
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceDiscrepanciesOverride(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", discrepancyId: "{discrepancy_id}", idempotencyKey, body);using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"reason_code": "no_payee_destination",
"note": "example"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceDiscrepanciesOverride(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{discrepancy_id}").IdempotencyKey(key).RemitDiscrepancyOverrideRequest(body).Execute()body := strings.NewReader(`{
"reason_code": "no_payee_destination",
"note": "example"
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/discrepancies/%7Bdiscrepancy_id%7D/override", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "discrepancy",
"kind": "recomputation_mismatch",
"status": "open",
"submitted": {
"amount": 1234567,
"currency": "NGN"
},
"recomputed": {
"amount": 1234567,
"currency": "NGN"
},
"line": 1,
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"difference": {
"amount": 1234567,
"currency": "NGN"
},
"reason_code": "no_payee_destination",
"overridden_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
/v1/remittance/imports#List file imports
remittance.imports.list
Lists your previous file submissions with their validation reports.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
Returns
A page of imports.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Import
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
8 fields of Import
id
string
requiredThe import's identifier, assigned at POST /v1/remittance/imports and starting remit_authority_rail_instruction_. It never changes; pass it as import_id at GET /v1/remittance/imports/{import_id} to read the validation report.
object
always "remittance_import"
requiredAlways remittance_import. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredvalidating while the rows are checked, pending_acceptance once the report is back, accepted or rejected once you accept or reject the instruction set it produced (instruction_set_id). Nothing is committed before accepted.
validatingpending_acceptanceacceptedrejectedinstruction_set_id
string · nullable
optionalThe id of the instruction set made from the file, starting remit_authority_rail_instruction_, or null until there is one. Read it at GET /v1/remittance/instruction_sets/{instruction_set_id}, accept or reject it, or list its discrepancies.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), starting_after (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/imports?limit=25" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), starting_after (optional)
const result = await api.remittanceImportsList({ limit: 25 });// query parameters: limit (optional), starting_after (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/imports?limit=25', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), starting_after (optional)
result = api.remittance_imports_list(limit=25)import os
import requests
# query parameters: limit (optional), starting_after (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/imports?limit=25',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), starting_after (optional)
$result = $api->remittanceImportsList(limit: 25);<?php
// query parameters: limit (optional), starting_after (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/imports?limit=25');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), starting_after (optional)
var result = api.remittanceImportsList(25, null);// query parameters: limit (optional), starting_after (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/imports?limit=25"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), starting_after (optional)
var result = api.RemittanceImportsList(limit: 25);// query parameters: limit (optional), starting_after (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/imports?limit=25");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), starting_after (optional)
result, _, err := client.REMITAPI.RemittanceImportsList(ctx).Limit(25).Execute()// query parameters: limit (optional), starting_after (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/imports?limit=25", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_import",
"livemode": true,
"mocked": true,
"status": "validating",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
],
"has_more": true
}
/v1/remittance/imports#Submit an instruction set as a file
remittance.imports.create
For a payroll system that can't call an API. Send a CSV or XLSX file and you get the same validation report the API route returns. Everything from here on behaves the same whichever way you submitted.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
The import, with its validation report.
id
string
requiredThe import's identifier, assigned at POST /v1/remittance/imports and starting remit_authority_rail_instruction_. It never changes; pass it as import_id at GET /v1/remittance/imports/{import_id} to read the validation report.
object
always "remittance_import"
requiredAlways remittance_import. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredvalidating while the rows are checked, pending_acceptance once the report is back, accepted or rejected once you accept or reject the instruction set it produced (instruction_set_id). Nothing is committed before accepted.
validatingpending_acceptanceacceptedrejectedinstruction_set_id
string · nullable
optionalThe id of the instruction set made from the file, starting remit_authority_rail_instruction_, or null until there is one. Read it at GET /v1/remittance/instruction_sets/{instruction_set_id}, accept or reject it, or list its discrepancies.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/imports" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceImportsCreate({});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/imports', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_imports_create()import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/imports',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceImportsCreate();<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/imports');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceImportsCreate();var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/imports"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceImportsCreate();using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/imports");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceImportsCreate(ctx).Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/imports", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_import",
"livemode": true,
"mocked": true,
"status": "validating",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/imports/{import_id}#Retrieve an import
remittance.imports.retrieve
You get the import with a report naming every row that failed and why.
Path parameters
import_id
string
requiredThe import's identifier, from the id returned by POST /v1/remittance/imports or listed at GET /v1/remittance/imports. It starts with remit_authority_rail_instruction_.
Returns
The import.
id
string
requiredThe import's identifier, assigned at POST /v1/remittance/imports and starting remit_authority_rail_instruction_. It never changes; pass it as import_id at GET /v1/remittance/imports/{import_id} to read the validation report.
object
always "remittance_import"
requiredAlways remittance_import. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredvalidating while the rows are checked, pending_acceptance once the report is back, accepted or rejected once you accept or reject the instruction set it produced (instruction_set_id). Nothing is committed before accepted.
validatingpending_acceptanceacceptedrejectedinstruction_set_id
string · nullable
optionalThe id of the instruction set made from the file, starting remit_authority_rail_instruction_, or null until there is one. Read it at GET /v1/remittance/instruction_sets/{instruction_set_id}, accept or reject it, or list its discrepancies.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceImportsRetrieve({ importId: '{import_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_imports_retrieve(import_id='{import_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceImportsRetrieve(import_id: '{import_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceImportsRetrieve("{import_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceImportsRetrieve(importId: "{import_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceImportsRetrieve(ctx, "{import_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/imports/%7Bimport_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_import",
"livemode": true,
"mocked": true,
"status": "validating",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/obligations#List statutory obligations
remittance.obligations.list
What you owe, to which authority, for which period, and what's left to pay after everything settled so far.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
authority_id
string
optionalReturn only what's owed to this authority, by its id as listed at GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. Leave it out to get every authority.
period
string
optionalReturn only obligations for this month, as YYYY-MM, such as 2026-09. Leave it out to get every period.
settled
boolean
optionaltrue for obligations with nothing left to pay, false for those with a balance outstanding. Leave it out to get both.
Returns
A page of obligations.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Obligation
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
12 fields of Obligation
id
string
requiredThe obligation's identifier, assigned when you accept an instruction set or record one at POST /v1/remittance/obligations, starting remit_authority_rail_obligation_. It never changes; pass it as obligation_id to retrieve it.
object
always "obligation"
requiredAlways obligation. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
authority_id
string
requiredThe authority the amount is owed to: its id from GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. GET /v1/remittance/authorities/{authority_id} gives its name, tier and capabilities; filter obligations by it.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you filter and match on.
period
string
requiredThe month the liability arises from, as YYYY-MM, such as 2026-09. One obligation covers one authority for one period; filter the list by it with the period query.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
settled
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
balance
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
deadline
string · date
requiredDerived from the pack calendar rules, never entered by hand.
receipt_ids
array of string
optionalThe id of each vaulted receipt that settles against this obligation, empty until one is vaulted. Retrieve a receipt at GET /v1/remittance/receipts/{receipt_id} for the authority's reference and the document.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
const result = await api.remittanceObligationsList({ limit: 25, authorityId: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', period: '2026-09', settled: false });// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
result = api.remittance_obligations_list(limit=25, authority_id='remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', period='2026-09', settled=false)import os
import requests
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
$result = $api->remittanceObligationsList(limit: 25, authority_id: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', period: '2026-09', settled: false);<?php
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
var result = api.remittanceObligationsList(25, null, "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "2026-09", false);// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
var result = api.RemittanceObligationsList(limit: 25, authorityId: "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", period: "2026-09", settled: false);// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
result, _, err := client.REMITAPI.RemittanceObligationsList(ctx).Limit(25).AuthorityId("remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Period("2026-09").Settled(false).Execute()// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional), settled (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/obligations?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09&settled=false", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "obligation",
"livemode": true,
"mocked": true,
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"settled": {
"amount": 1234567,
"currency": "NGN"
},
"balance": {
"amount": 1234567,
"currency": "NGN"
},
"deadline": "2026-09-01",
"authority_name": "Rivers State Internal Revenue Service",
"receipt_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
],
"has_more": true
}
/v1/remittance/obligations#Record an obligation
remittance.obligations.create
Record what you owe, to whom, for which period. Obligations normally arise from an accepted instruction set. Use this to record one directly, for a liability that predates your use of Droomwork.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body optional
authority
string
optionalThe authority the amount is owed to.
period
string
optionalThe period the obligation arises from, as YYYY-MM.
Returns
The recorded obligation.
id
string
requiredThe obligation's identifier, assigned when you accept an instruction set or record one at POST /v1/remittance/obligations, starting remit_authority_rail_obligation_. It never changes; pass it as obligation_id to retrieve it.
object
always "obligation"
requiredAlways obligation. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
authority_id
string
requiredThe authority the amount is owed to: its id from GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. GET /v1/remittance/authorities/{authority_id} gives its name, tier and capabilities; filter obligations by it.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you filter and match on.
period
string
requiredThe month the liability arises from, as YYYY-MM, such as 2026-09. One obligation covers one authority for one period; filter the list by it with the period query.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
settled
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
balance
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
deadline
string · date
requiredDerived from the pack calendar rules, never entered by hand.
receipt_ids
array of string
optionalThe id of each vaulted receipt that settles against this obligation, empty until one is vaulted. Retrieve a receipt at GET /v1/remittance/receipts/{receipt_id} for the authority's reference and the document.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/obligations" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"authority":"example","period":"2026-09"}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceObligationsCreate({});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/obligations', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"authority": "example",
"period": "2026-09"
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_obligations_create()import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/obligations',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"authority": "example", "period": "2026-09"},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceObligationsCreate();<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/obligations');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"authority":"example","period":"2026-09"}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceObligationsCreate();var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/obligations"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"authority": "example",
"period": "2026-09"
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceObligationsCreate();using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/obligations");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"authority": "example",
"period": "2026-09"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceObligationsCreate(ctx).Execute()body := strings.NewReader(`{
"authority": "example",
"period": "2026-09"
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/obligations", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "obligation",
"livemode": true,
"mocked": true,
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"settled": {
"amount": 1234567,
"currency": "NGN"
},
"balance": {
"amount": 1234567,
"currency": "NGN"
},
"deadline": "2026-09-01",
"authority_name": "Rivers State Internal Revenue Service",
"receipt_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
/v1/remittance/obligations/{obligation_id}#Retrieve an obligation
remittance.obligations.retrieve
You get the liability, what has settled against it, and the balance.
Path parameters
obligation_id
string
requiredThe obligation's identifier, from the id of an obligation listed at GET /v1/remittance/obligations or recorded at POST /v1/remittance/obligations. It starts with remit_authority_rail_obligation_.
Returns
The obligation.
id
string
requiredThe obligation's identifier, assigned when you accept an instruction set or record one at POST /v1/remittance/obligations, starting remit_authority_rail_obligation_. It never changes; pass it as obligation_id to retrieve it.
object
always "obligation"
requiredAlways obligation. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
authority_id
string
requiredThe authority the amount is owed to: its id from GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. GET /v1/remittance/authorities/{authority_id} gives its name, tier and capabilities; filter obligations by it.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you filter and match on.
period
string
requiredThe month the liability arises from, as YYYY-MM, such as 2026-09. One obligation covers one authority for one period; filter the list by it with the period query.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
settled
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
balance
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
deadline
string · date
requiredDerived from the pack calendar rules, never entered by hand.
receipt_ids
array of string
optionalThe id of each vaulted receipt that settles against this obligation, empty until one is vaulted. Retrieve a receipt at GET /v1/remittance/receipts/{receipt_id} for the authority's reference and the document.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceObligationsRetrieve({ obligationId: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_obligations_retrieve(obligation_id='remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceObligationsRetrieve(obligation_id: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceObligationsRetrieve("remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceObligationsRetrieve(obligationId: "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceObligationsRetrieve(ctx, "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/obligations/remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "obligation",
"livemode": true,
"mocked": true,
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"settled": {
"amount": 1234567,
"currency": "NGN"
},
"balance": {
"amount": 1234567,
"currency": "NGN"
},
"deadline": "2026-09-01",
"authority_name": "Rivers State Internal Revenue Service",
"receipt_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
/v1/remittance/calendar_entries#List filing deadlines
remittance.calendar_entries.list
Amounts, deadlines and the penalty formula for each, taken from the jurisdiction pack and never entered by hand. Due soon alerts reach you as webhooks at the lead time you configure.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
due_before
string
optionalReturn only deadlines that fall before this date, as YYYY-MM-DD, such as 2026-09-30. Leave it out to get every deadline.
authority_id
string
optionalReturn only the deadlines for this authority, by its id as listed at GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. Leave it out to get every authority.
Returns
A page of calendar entries.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of CalendarEntry
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
10 fields of CalendarEntry
id
string
requiredThe deadline's identifier, as listed at GET /v1/remittance/calendar_entries, starting remit_authority_rail_obligation_. It never changes; pass it as calendar_entry_id at GET /v1/remittance/calendar_entries/{calendar_entry_id}.
object
always "calendar_entry"
requiredAlways calendar_entry. Tells you which kind of record you are looking at, so one handler can read any response.
authority_id
string
requiredThe authority this deadline is for: its id from GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. GET /v1/remittance/authorities/{authority_id} gives its name, tier and capabilities; filter the calendar by it.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you filter and match on.
period
string
requiredThe month the filing covers, as YYYY-MM, such as 2026-09. The deadline and amount are for this period alone.
deadline
string · date
requiredThe date the filing is due, as YYYY-MM-DD, such as 2026-09-01, set by the jurisdiction pack's calendar rules and never by anything you enter. File after it and penalty_formula says what that costs.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
penalty_formula
string
optionalPublished from the pack as a formula rather than a computed figure, because the amount depends on when you actually file.
lead_time_days
integer
optionalHow far ahead the due soon alert fires.
pack_version
string
optionalThe version of the jurisdiction pack this entry came from, such as 2026.08.1. Keep it with the entry, so you can show which rules set the deadline and the penalty formula.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), due_before (optional), authority_id (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), due_before (optional), authority_id (optional)
const result = await api.remittanceCalendarEntriesList({ limit: 25, dueBefore: 'Fri Jan 01 2027 01:00:00 GMT+0100 (West Africa Time)', authorityId: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });// query parameters: limit (optional), due_before (optional), authority_id (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), due_before (optional), authority_id (optional)
result = api.remittance_calendar_entries_list(limit=25, due_before='Fri Jan 01 2027 01:00:00 GMT+0100 (West Africa Time)', authority_id='remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
# query parameters: limit (optional), due_before (optional), authority_id (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), due_before (optional), authority_id (optional)
$result = $api->remittanceCalendarEntriesList(limit: 25, due_before: 'Fri Jan 01 2027 01:00:00 GMT+0100 (West Africa Time)', authority_id: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
// query parameters: limit (optional), due_before (optional), authority_id (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), due_before (optional), authority_id (optional)
var result = api.remittanceCalendarEntriesList(25, "Fri Jan 01 2027 01:00:00 GMT+0100 (West Africa Time)", "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");// query parameters: limit (optional), due_before (optional), authority_id (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), due_before (optional), authority_id (optional)
var result = api.RemittanceCalendarEntriesList(limit: 25, dueBefore: "Fri Jan 01 2027 01:00:00 GMT+0100 (West Africa Time)", authorityId: "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");// query parameters: limit (optional), due_before (optional), authority_id (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), due_before (optional), authority_id (optional)
result, _, err := client.REMITAPI.RemittanceCalendarEntriesList(ctx).Limit(25).DueBefore("Fri Jan 01 2027 01:00:00 GMT+0100 (West Africa Time)").AuthorityId("remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()// query parameters: limit (optional), due_before (optional), authority_id (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/calendar_entries?limit=25&due_before=Fri%20Jan%2001%202027%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "calendar_entry",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"deadline": "2026-09-01",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"authority_name": "Rivers State Internal Revenue Service",
"penalty_formula": "10 percent of the unpaid amount plus interest at the CBN rate per annum",
"lead_time_days": 1,
"pack_version": "2026.08.1"
}
],
"has_more": true
}
/v1/remittance/calendar_entries/{calendar_entry_id}#Retrieve a filing deadline
remittance.calendar_entries.retrieve
You get the deadline with its penalty formula and the pack version it came from.
Path parameters
calendar_entry_id
string
requiredThe deadline's identifier, from the id of an entry listed at GET /v1/remittance/calendar_entries. It starts with remit_authority_rail_obligation_.
Returns
The calendar entry.
id
string
requiredThe deadline's identifier, as listed at GET /v1/remittance/calendar_entries, starting remit_authority_rail_obligation_. It never changes; pass it as calendar_entry_id at GET /v1/remittance/calendar_entries/{calendar_entry_id}.
object
always "calendar_entry"
requiredAlways calendar_entry. Tells you which kind of record you are looking at, so one handler can read any response.
authority_id
string
requiredThe authority this deadline is for: its id from GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. GET /v1/remittance/authorities/{authority_id} gives its name, tier and capabilities; filter the calendar by it.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you filter and match on.
period
string
requiredThe month the filing covers, as YYYY-MM, such as 2026-09. The deadline and amount are for this period alone.
deadline
string · date
requiredThe date the filing is due, as YYYY-MM-DD, such as 2026-09-01, set by the jurisdiction pack's calendar rules and never by anything you enter. File after it and penalty_formula says what that costs.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
penalty_formula
string
optionalPublished from the pack as a formula rather than a computed figure, because the amount depends on when you actually file.
lead_time_days
integer
optionalHow far ahead the due soon alert fires.
pack_version
string
optionalThe version of the jurisdiction pack this entry came from, such as 2026.08.1. Keep it with the entry, so you can show which rules set the deadline and the penalty formula.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceCalendarEntriesRetrieve({ calendarEntryId: '{calendar_entry_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_calendar_entries_retrieve(calendar_entry_id='{calendar_entry_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceCalendarEntriesRetrieve(calendar_entry_id: '{calendar_entry_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceCalendarEntriesRetrieve("{calendar_entry_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceCalendarEntriesRetrieve(calendarEntryId: "{calendar_entry_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceCalendarEntriesRetrieve(ctx, "{calendar_entry_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/calendar_entries/%7Bcalendar_entry_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "calendar_entry",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"deadline": "2026-09-01",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"authority_name": "Rivers State Internal Revenue Service",
"penalty_formula": "10 percent of the unpaid amount plus interest at the CBN rate per annum",
"lead_time_days": 1,
"pack_version": "2026.08.1"
}
/v1/remittance/authorities#List statutory authorities and what each supports
remittance.authorities.list
All 37 tax jurisdictions, plus the pension commission and administrators, NHF, NSITF, ITF and NHIA. Each shows you a capability flag and a tier.
Read the tier to know what to expect on timing. Never code against it: all three tiers present the same request, the same states, the same webhooks and the same evidence class.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
kind
string
optionalReturn only authorities of this kind: state_irs or federal_irs for tax, pension_commission or pension_administrator for pensions, nhf, nsitf, itf or nhia for the levies. Leave it out to get every kind.
state_irsfederal_irspension_commissionpension_administratornhfnsitfitfnhiatier
string
optionalReturn only authorities your filing reaches this way: direct_api, portal_automation or assisted_manual. Leave it out to get every tier; read a tier for timing, never as something to code against.
direct_apiportal_automationassisted_manualReturns
A page of authorities.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Authority
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
9 fields of Authority
id
string
requiredThe authority's identifier, as listed at GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. It never changes; pass it as authority_id to retrieve the authority, or to filter obligations and deadlines by it.
object
always "authority"
requiredAlways authority. Tells you which kind of record you are looking at, so one handler can read any response.
kind
string
requiredstate_irsfederal_irspension_commissionpension_administratornhfnsitfitfnhiatier
string
requiredHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualname
string
requiredThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. It's what appears as authority_name on obligations, legs and deadlines.
jurisdiction
string
optionalWhich jurisdiction the authority collects for, such as the state whose PAYE a State IRS receives. Use it to tell the 37 tax jurisdictions apart.
capabilities
object
requiredWhat this authority supports. Absent a capability, the endpoint refuses rather than pretends.
4 fields
file_return
boolean
optionaltrue when you can file an employer return with this authority through Droomwork. When it's false, a return for this authority is refused rather than pretended.
pay
boolean
optionaltrue when you can pay this authority through a remittance leg. When it's false, a leg for this authority is refused rather than pretended.
receipt_retrieval
boolean
optionaltrue when we can retrieve the receipt for a filing from this authority and vault it as your proof. When it's false, none is retrieved for you: record the one the authority issued at POST /v1/remittance/receipts.
schedule_upload
boolean
optionaltrue when the per-employee schedule behind a filing can be uploaded to this authority. When it's false, a schedule upload for it is refused rather than pretended.
credentials_held
boolean
optionalWhether you have supplied credentials for this authority.
expected_completion
string
optionalTypical time to a vaulted receipt at this tier.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), kind (optional), tier (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), kind (optional), tier (optional)
const result = await api.remittanceAuthoritiesList({ limit: 25, kind: 'state_irs', tier: 'direct_api' });// query parameters: limit (optional), kind (optional), tier (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), kind (optional), tier (optional)
result = api.remittance_authorities_list(limit=25, kind='state_irs', tier='direct_api')import os
import requests
# query parameters: limit (optional), kind (optional), tier (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), kind (optional), tier (optional)
$result = $api->remittanceAuthoritiesList(limit: 25, kind: 'state_irs', tier: 'direct_api');<?php
// query parameters: limit (optional), kind (optional), tier (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
import com.droomwork.sdk.model.*;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), kind (optional), tier (optional)
var result = api.remittanceAuthoritiesList(25, RemitAuthorityKind.fromValue("state_irs"), RemitAuthorityTier.fromValue("direct_api"));// query parameters: limit (optional), kind (optional), tier (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), kind (optional), tier (optional)
var result = api.RemittanceAuthoritiesList(limit: 25, kind: RemitAuthorityKind.StateIrs, tier: RemitAuthorityTier.DirectApi);// query parameters: limit (optional), kind (optional), tier (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), kind (optional), tier (optional)
result, _, err := client.REMITAPI.RemittanceAuthoritiesList(ctx).Limit(25).Kind(droomwork.RemitAuthorityKind("state_irs")).Tier(droomwork.RemitAuthorityTier("direct_api")).Execute()// query parameters: limit (optional), kind (optional), tier (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/authorities?limit=25&kind=state_irs&tier=direct_api", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "authority",
"kind": "state_irs",
"tier": "direct_api",
"name": "Rivers State Internal Revenue Service",
"capabilities": {
"file_return": true,
"pay": true,
"receipt_retrieval": true,
"schedule_upload": true
},
"jurisdiction": "Rivers State Internal Revenue Service",
"credentials_held": true,
"expected_completion": "under 5 minutes"
}
],
"has_more": true
}
/v1/remittance/authorities/{authority_id}#Retrieve an authority
remittance.authorities.retrieve
You get the authority with its tier and capabilities. When an authority moves from an assisted tier to a direct one, nothing changes on your side.
Path parameters
authority_id
string
requiredThe authority's identifier: the id of an authority listed at GET /v1/remittance/authorities, or the authority_id on an obligation, leg, receipt or calendar entry. It starts with remit_authority_rail_obligation_.
Returns
The authority.
id
string
requiredThe authority's identifier, as listed at GET /v1/remittance/authorities, starting remit_authority_rail_obligation_. It never changes; pass it as authority_id to retrieve the authority, or to filter obligations and deadlines by it.
object
always "authority"
requiredAlways authority. Tells you which kind of record you are looking at, so one handler can read any response.
kind
string
requiredstate_irsfederal_irspension_commissionpension_administratornhfnsitfitfnhiatier
string
requiredHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualname
string
requiredThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. It's what appears as authority_name on obligations, legs and deadlines.
jurisdiction
string
optionalWhich jurisdiction the authority collects for, such as the state whose PAYE a State IRS receives. Use it to tell the 37 tax jurisdictions apart.
capabilities
object
requiredWhat this authority supports. Absent a capability, the endpoint refuses rather than pretends.
4 fields
file_return
boolean
optionaltrue when you can file an employer return with this authority through Droomwork. When it's false, a return for this authority is refused rather than pretended.
pay
boolean
optionaltrue when you can pay this authority through a remittance leg. When it's false, a leg for this authority is refused rather than pretended.
receipt_retrieval
boolean
optionaltrue when we can retrieve the receipt for a filing from this authority and vault it as your proof. When it's false, none is retrieved for you: record the one the authority issued at POST /v1/remittance/receipts.
schedule_upload
boolean
optionaltrue when the per-employee schedule behind a filing can be uploaded to this authority. When it's false, a schedule upload for it is refused rather than pretended.
credentials_held
boolean
optionalWhether you have supplied credentials for this authority.
expected_completion
string
optionalTypical time to a vaulted receipt at this tier.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceAuthoritiesRetrieve({ authorityId: '{authority_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_authorities_retrieve(authority_id='{authority_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceAuthoritiesRetrieve(authority_id: '{authority_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceAuthoritiesRetrieve("{authority_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceAuthoritiesRetrieve(authorityId: "{authority_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceAuthoritiesRetrieve(ctx, "{authority_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/authorities/%7Bauthority_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "authority",
"kind": "state_irs",
"tier": "direct_api",
"name": "Rivers State Internal Revenue Service",
"capabilities": {
"file_return": true,
"pay": true,
"receipt_retrieval": true,
"schedule_upload": true
},
"jurisdiction": "Rivers State Internal Revenue Service",
"credentials_held": true,
"expected_completion": "under 5 minutes"
}
/v1/remittance/remittances#List remittances
remittance.remittances.list
Lists your remittances, newest first.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
status
string
optionalReturn only remittances in one state: draft (created, not yet approved), approved, executing (legs running), completed, partially_completed (some legs failed) or failed. Leave it out to get every state.
draftapprovedexecutingcompletedpartially_completedfailedReturns
A page of remittances.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Remittance
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
11 fields of Remittance
id
string
requiredThe remittance's identifier, first returned by POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_ and never changes. Pass it as remittance_id wherever a call names this remittance.
object
always "remittance"
requiredAlways remittance. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requireddraftapprovedexecutingcompletedpartially_completedfailedinstruction_set_id
string
requiredThe id of the accepted instruction set whose figures the legs pay, from POST /v1/remittance/instruction_sets, starting with remit_authority_rail_instruction_. Retrieve it at GET /v1/remittance/instruction_sets/{instruction_set_id}.
period
string
optionalThe month the remittance pays for, as YYYY-MM, such as 2026-09. It's the period of the instruction set it was created from.
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
legs
array of Leg
requiredOne leg per authority the remittance pays, each with its own state, amount and receipt. A leg runs on its own, so one authority being down never holds the others; read each to see what settled where.
11 fields of Leg
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
approved_by
string · nullable
optionalWho approved the remittance: the actor that called approve. null while it is still draft, and execution is refused until a person is named here.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), starting_after (optional), status (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), starting_after (optional), status (optional)
const result = await api.remittanceRemittancesList({ limit: 25, status: 'draft' });// query parameters: limit (optional), starting_after (optional), status (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), starting_after (optional), status (optional)
result = api.remittance_remittances_list(limit=25, status='draft')import os
import requests
# query parameters: limit (optional), starting_after (optional), status (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), starting_after (optional), status (optional)
$result = $api->remittanceRemittancesList(limit: 25, status: 'draft');<?php
// query parameters: limit (optional), starting_after (optional), status (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
import com.droomwork.sdk.model.*;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), starting_after (optional), status (optional)
var result = api.remittanceRemittancesList(25, null, RemitRemittanceStatus.fromValue("draft"));// query parameters: limit (optional), starting_after (optional), status (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), starting_after (optional), status (optional)
var result = api.RemittanceRemittancesList(limit: 25, status: RemitRemittanceStatus.Draft);// query parameters: limit (optional), starting_after (optional), status (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), starting_after (optional), status (optional)
result, _, err := client.REMITAPI.RemittanceRemittancesList(ctx).Limit(25).Status(droomwork.RemitRemittanceStatus("draft")).Execute()// query parameters: limit (optional), starting_after (optional), status (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/remittances?limit=25&status=draft", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance",
"livemode": true,
"mocked": true,
"status": "draft",
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"legs": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
],
"total": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
],
"has_more": true
}
/v1/remittance/remittances#Create a remittance from an accepted instruction set
remittance.remittances.create
You get one leg per authority. Each leg executes on its own, so a single authority being unreachable never blocks the rest.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body
instruction_set_id
string
requiredThe id of the instruction set to remit, from POST /v1/remittance/instruction_sets; it starts with remit_authority_rail_instruction_ and must be accepted first. You get one leg per authority it names, or only those in authority_ids.
authority_ids
array of string
optionalDefaults to every authority named in the instruction set.
Returns
The remittance, in draft, with a leg per authority.
id
string
requiredThe remittance's identifier, first returned by POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_ and never changes. Pass it as remittance_id wherever a call names this remittance.
object
always "remittance"
requiredAlways remittance. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requireddraftapprovedexecutingcompletedpartially_completedfailedinstruction_set_id
string
requiredThe id of the accepted instruction set whose figures the legs pay, from POST /v1/remittance/instruction_sets, starting with remit_authority_rail_instruction_. Retrieve it at GET /v1/remittance/instruction_sets/{instruction_set_id}.
period
string
optionalThe month the remittance pays for, as YYYY-MM, such as 2026-09. It's the period of the instruction set it was created from.
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
legs
array of Leg
requiredOne leg per authority the remittance pays, each with its own state, amount and receipt. A leg runs on its own, so one authority being down never holds the others; read each to see what settled where.
11 fields of Leg
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
approved_by
string · nullable
optionalWho approved the remittance: the actor that called approve. null while it is still draft, and execution is refused until a person is named here.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/remittances" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"instruction_set_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authority_ids":["sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceRemittancesCreate({
idempotencyKey: crypto.randomUUID(),
remitRemittanceCreateRequest: {"instructionSetId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authorityIds":["sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]},
});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_remittances_create(body={"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "authority_ids": ["sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]})import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/remittances',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "authority_ids": ["sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceRemittancesCreate($idempotencyKey, json_decode('{"instruction_set_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authority_ids":["sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]}', true));<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"instruction_set_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authority_ids":["sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceRemittancesCreate(idempotencyKey, body);var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceRemittancesCreate(idempotencyKey, body);using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/remittances");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceRemittancesCreate(ctx).IdempotencyKey(key).RemitRemittanceCreateRequest(body).Execute()body := strings.NewReader(`{
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_ids": [
"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/remittances", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance",
"livemode": true,
"mocked": true,
"status": "draft",
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"legs": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
],
"total": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/remittances/{remittance_id}#Retrieve a remittance
remittance.remittances.retrieve
You get the remittance with the state of every leg.
Path parameters
remittance_id
string
requiredThe remittance's identifier: the id of a remittance you created at POST /v1/remittance/remittances or listed at GET /v1/remittance/remittances. It starts with remit_authority_rail_remittance_.
Returns
The remittance.
id
string
requiredThe remittance's identifier, first returned by POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_ and never changes. Pass it as remittance_id wherever a call names this remittance.
object
always "remittance"
requiredAlways remittance. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requireddraftapprovedexecutingcompletedpartially_completedfailedinstruction_set_id
string
requiredThe id of the accepted instruction set whose figures the legs pay, from POST /v1/remittance/instruction_sets, starting with remit_authority_rail_instruction_. Retrieve it at GET /v1/remittance/instruction_sets/{instruction_set_id}.
period
string
optionalThe month the remittance pays for, as YYYY-MM, such as 2026-09. It's the period of the instruction set it was created from.
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
legs
array of Leg
requiredOne leg per authority the remittance pays, each with its own state, amount and receipt. A leg runs on its own, so one authority being down never holds the others; read each to see what settled where.
11 fields of Leg
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
approved_by
string · nullable
optionalWho approved the remittance: the actor that called approve. null while it is still draft, and execution is refused until a person is named here.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceRemittancesRetrieve({ remittanceId: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_remittances_retrieve(remittance_id='remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceRemittancesRetrieve(remittance_id: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceRemittancesRetrieve("remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceRemittancesRetrieve(remittanceId: "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceRemittancesRetrieve(ctx, "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance",
"livemode": true,
"mocked": true,
"status": "draft",
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"legs": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
],
"total": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/remittances/{remittance_id}/approve#Approve a remittance and release every leg
remittance.remittances.approve
One approval releases every leg. Each then executes on its own against its own authority.
Path parameters
remittance_id
string
requiredThe remittance's identifier: the id of a remittance you created at POST /v1/remittance/remittances or listed at GET /v1/remittance/remittances. It starts with remit_authority_rail_remittance_.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
Approved. Legs begin executing.
id
string
requiredThe remittance's identifier, first returned by POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_ and never changes. Pass it as remittance_id wherever a call names this remittance.
object
always "remittance"
requiredAlways remittance. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requireddraftapprovedexecutingcompletedpartially_completedfailedinstruction_set_id
string
requiredThe id of the accepted instruction set whose figures the legs pay, from POST /v1/remittance/instruction_sets, starting with remit_authority_rail_instruction_. Retrieve it at GET /v1/remittance/instruction_sets/{instruction_set_id}.
period
string
optionalThe month the remittance pays for, as YYYY-MM, such as 2026-09. It's the period of the instruction set it was created from.
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
legs
array of Leg
requiredOne leg per authority the remittance pays, each with its own state, amount and receipt. A leg runs on its own, so one authority being down never holds the others; read each to see what settled where.
11 fields of Leg
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
approved_by
string · nullable
optionalWho approved the remittance: the actor that called approve. null while it is still draft, and execution is refused until a person is named here.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceRemittancesApprove({ remittanceId: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_remittances_approve(remittance_id='remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceRemittancesApprove(remittance_id: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceRemittancesApprove("remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceRemittancesApprove(remittanceId: "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceRemittancesApprove(ctx, "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance",
"livemode": true,
"mocked": true,
"status": "draft",
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"legs": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
],
"total": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/remittances/{remittance_id}/legs#List the legs of a remittance
remittance.legs.list
You get one leg per authority, each with its own state and its own receipt.
Path parameters
remittance_id
string
requiredThe remittance's identifier: the id of a remittance you created at POST /v1/remittance/remittances or listed at GET /v1/remittance/remittances. It starts with remit_authority_rail_remittance_.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
status
string
optionalReturn only legs in one state: pending (not yet executed), executing, awaiting_receipt (filed), completed (receipt vaulted), quarantined (receipt disagreed with the leg) or failed (needs a retry). Leave it out to get every state.
pendingexecutingawaiting_receiptcompletedquarantinedfailedReturns
A page of legs.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Leg
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
11 fields of Leg
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), status (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), status (optional)
const result = await api.remittanceLegsList({ remittanceId: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', limit: 25, status: 'pending' });// query parameters: limit (optional), status (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), status (optional)
result = api.remittance_legs_list(remittance_id='remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', limit=25, status='pending')import os
import requests
# query parameters: limit (optional), status (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), status (optional)
$result = $api->remittanceLegsList(remittance_id: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', limit: 25, status: 'pending');<?php
// query parameters: limit (optional), status (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
import com.droomwork.sdk.model.*;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), status (optional)
var result = api.remittanceLegsList("remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", 25, RemitLegStatus.fromValue("pending"));// query parameters: limit (optional), status (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), status (optional)
var result = api.RemittanceLegsList(remittanceId: "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", limit: 25, status: RemitLegStatus.Pending);// query parameters: limit (optional), status (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), status (optional)
result, _, err := client.REMITAPI.RemittanceLegsList(ctx, "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Limit(25).Status(droomwork.RemitLegStatus("pending")).Execute()// query parameters: limit (optional), status (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs?limit=25&status=pending", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
],
"has_more": true
}
/v1/remittance/remittances/{remittance_id}/legs/{leg_id}#Retrieve a leg
remittance.legs.retrieve
You get the leg with its state. A leg reaches completed only once its receipt is vaulted; a filing reported as successful is not enough on its own.
Path parameters
remittance_id
string
requiredThe remittance's identifier: the id of a remittance you created at POST /v1/remittance/remittances or listed at GET /v1/remittance/remittances. It starts with remit_authority_rail_remittance_.
leg_id
string
requiredThe leg's identifier: the id of a leg in legs on the remittance from POST /v1/remittance/remittances, or listed at GET /v1/remittance/remittances/{remittance_id}/legs. It belongs to the remittance in the path.
Returns
The leg.
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceLegsRetrieve({ remittanceId: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', legId: '{leg_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_legs_retrieve(remittance_id='remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', leg_id='{leg_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceLegsRetrieve(remittance_id: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', leg_id: '{leg_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceLegsRetrieve("remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{leg_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceLegsRetrieve(remittanceId: "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", legId: "{leg_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceLegsRetrieve(ctx, "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{leg_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
/v1/remittance/remittances/{remittance_id}/legs/{leg_id}/retry#Retry a failed leg
remittance.legs.retry
Retries one authority without touching the others. A retry after a timeout cannot file twice.
Path parameters
remittance_id
string
requiredThe remittance's identifier: the id of a remittance you created at POST /v1/remittance/remittances or listed at GET /v1/remittance/remittances. It starts with remit_authority_rail_remittance_.
leg_id
string
requiredThe leg's identifier: the id of a leg in legs on the remittance from POST /v1/remittance/remittances, or listed at GET /v1/remittance/remittances/{remittance_id}/legs. It belongs to the remittance in the path.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
Retry accepted.
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceLegsRetry({ remittanceId: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', legId: '{leg_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_legs_retry(remittance_id='remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', leg_id='{leg_id}')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceLegsRetry(remittance_id: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', leg_id: '{leg_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceLegsRetry("remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{leg_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceLegsRetry(remittanceId: "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", legId: "{leg_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceLegsRetry(ctx, "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "{leg_id}").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/legs/%7Bleg_id%7D/retry", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
/v1/remittance/receipts#List vaulted receipts
remittance.receipts.list
Your receipts, in a vault that is append only and hash chained. Every receipt links to its obligation, its leg, the schedule lines it covers and the payroll trace references behind them.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
authority_id
string
optionalReturn only receipts issued by one authority: its id from GET /v1/remittance/authorities, or the authority_id on a leg or obligation, starting with remit_authority_rail_obligation_. Leave it out to get every authority.
period
string
optionalReturn only receipts whose payment covers one month, as YYYY-MM, such as 2026-09: the period each receipt carries. Leave it out to get every period.
Returns
A page of receipts.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Receipt
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
17 fields of Receipt
id
string
requiredThe receipt's identifier, starting with remit_authority_rail_receipt_; it never changes. It is the receipt_id on the leg it proves and in receipt_ids on its obligation; pass it as receipt_id to GET /v1/remittance/receipts/{receipt_id}.
object
always "remittance_receipt"
requiredAlways remittance_receipt. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
leg_id
string · nullable
optionalThe id of the leg this receipt proves paid, from legs on a remittance or GET /v1/remittance/remittances/{remittance_id}/legs; vaulting the receipt takes that leg to completed. null when the receipt is not tied to a leg.
obligation_id
string · nullable
optionalThe id of the obligation this receipt settles against, from GET /v1/remittance/obligations, starting with remit_authority_rail_obligation_; the receipt also appears in its receipt_ids. null when not tied to an obligation.
authority_id
string
requiredThe id of the authority that issued this receipt, from GET /v1/remittance/authorities, starting with remit_authority_rail_obligation_; filter the list by it. It must agree with the leg's authority_id, or the receipt is quarantined.
period
string
requiredThe month the payment covers, as YYYY-MM, such as 2026-09; filter the list by it with the period query. It must agree with the leg's period, or the receipt is quarantined.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
authority_reference
string
optionalThe reference the authority itself issued.
evidence_class
string
requiredThe same classes apply whichever tier filed. An assisted manual filing carries a receipt reference, a document scan and an operator attestation under dual control, which is the same evidence class as an API filing.
authority_api_receiptportal_receiptassisted_manual_attesteddocument_url
string · uri · nullable
optionalWhere to fetch the receipt document the authority issued, as a URL. Present for an assisted manual filing, where you supplied the scan; null when there is no document.
hash
string
requiredThis receipt position in the append only chain.
previous_hash
string
requiredThe hash of the receipt vaulted just before this one. Each receipt carries the last one's hash, so you can walk the chain back and confirm nothing was changed or removed.
trace_references
array of string
optionalThe payroll trace references this receipt covers.
attested_by
array of string
optionalTwo actors for an assisted manual filing, under dual control.
vaulted_at
string · date-time
optionalWhen the receipt was hash chained into the vault, as an RFC 3339 timestamp in UTC. From this moment it never changes, and the leg it belongs to can reach completed.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
const result = await api.remittanceReceiptsList({ limit: 25, authorityId: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', period: '2026-09' });// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
result = api.remittance_receipts_list(limit=25, authority_id='remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', period='2026-09')import os
import requests
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
$result = $api->remittanceReceiptsList(limit: 25, authority_id: 'remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', period: '2026-09');<?php
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
var result = api.remittanceReceiptsList(25, null, "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "2026-09");// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
var result = api.RemittanceReceiptsList(limit: 25, authorityId: "remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", period: "2026-09");// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
result, _, err := client.REMITAPI.RemittanceReceiptsList(ctx).Limit(25).AuthorityId("remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Period("2026-09").Execute()// query parameters: limit (optional), starting_after (optional), authority_id (optional), period (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/receipts?limit=25&authority_id=remit_authority_rail_obligation_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&period=2026-09", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_receipt",
"livemode": true,
"mocked": true,
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"evidence_class": "authority_api_receipt",
"hash": "sha256:9f2c1e0043a1b8",
"previous_hash": "sha256:9f2c1e0043a1b8",
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"obligation_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"document_url": "https://files.sandbox.droomwork.com/example",
"trace_references": [
"paye-2026-09-rivers"
],
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
],
"vaulted_at": "2026-09-01T09:00:00Z"
}
],
"has_more": true
}
/v1/remittance/receipts#Record a receipt from an assisted manual filing
remittance.receipts.create
For authorities with no machine interface. Send the receipt reference, a scan of the document and an operator attestation under dual control. It carries the same evidence class as an API filing.
Dual control means two actors. A single credential is not enough on this endpoint.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body
leg_id
string
requiredThe id of the leg you filed by hand, from legs on the remittance or GET /v1/remittance/remittances/{remittance_id}/legs: one whose authority has no machine interface. The receipt is vaulted against it, which takes the leg to completed.
authority_reference
string
requiredThe reference the authority put on its receipt, exactly as issued, such as paye-2026-09-rivers. It comes back as authority_reference on the vaulted receipt.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
document_url
string · uri
requiredA scan of the receipt the authority issued.
attested_by
array of string
requiredTwo distinct actors. Dual control, so one credential is not enough.
Returns
The vaulted receipt.
id
string
requiredThe receipt's identifier, starting with remit_authority_rail_receipt_; it never changes. It is the receipt_id on the leg it proves and in receipt_ids on its obligation; pass it as receipt_id to GET /v1/remittance/receipts/{receipt_id}.
object
always "remittance_receipt"
requiredAlways remittance_receipt. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
leg_id
string · nullable
optionalThe id of the leg this receipt proves paid, from legs on a remittance or GET /v1/remittance/remittances/{remittance_id}/legs; vaulting the receipt takes that leg to completed. null when the receipt is not tied to a leg.
obligation_id
string · nullable
optionalThe id of the obligation this receipt settles against, from GET /v1/remittance/obligations, starting with remit_authority_rail_obligation_; the receipt also appears in its receipt_ids. null when not tied to an obligation.
authority_id
string
requiredThe id of the authority that issued this receipt, from GET /v1/remittance/authorities, starting with remit_authority_rail_obligation_; filter the list by it. It must agree with the leg's authority_id, or the receipt is quarantined.
period
string
requiredThe month the payment covers, as YYYY-MM, such as 2026-09; filter the list by it with the period query. It must agree with the leg's period, or the receipt is quarantined.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
authority_reference
string
optionalThe reference the authority itself issued.
evidence_class
string
requiredThe same classes apply whichever tier filed. An assisted manual filing carries a receipt reference, a document scan and an operator attestation under dual control, which is the same evidence class as an API filing.
authority_api_receiptportal_receiptassisted_manual_attesteddocument_url
string · uri · nullable
optionalWhere to fetch the receipt document the authority issued, as a URL. Present for an assisted manual filing, where you supplied the scan; null when there is no document.
hash
string
requiredThis receipt position in the append only chain.
previous_hash
string
requiredThe hash of the receipt vaulted just before this one. Each receipt carries the last one's hash, so you can walk the chain back and confirm nothing was changed or removed.
trace_references
array of string
optionalThe payroll trace references this receipt covers.
attested_by
array of string
optionalTwo actors for an assisted manual filing, under dual control.
vaulted_at
string · date-time
optionalWhen the receipt was hash chained into the vault, as an RFC 3339 timestamp in UTC. From this moment it never changes, and the leg it belongs to can reach completed.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/receipts" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"leg_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authority_reference":"paye-2026-09-rivers","amount":{"amount":1234567,"currency":"NGN"},"document_url":"https://files.sandbox.droomwork.com/example","attested_by":["usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReceiptsCreate({
idempotencyKey: crypto.randomUUID(),
remitReceiptCreateRequest: {"legId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authorityReference":"paye-2026-09-rivers","amount":{"amount":1234567,"currency":"NGN"},"documentUrl":"https://files.sandbox.droomwork.com/example","attestedBy":["usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]},
});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/receipts', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"document_url": "https://files.sandbox.droomwork.com/example",
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_receipts_create(body={"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "authority_reference": "paye-2026-09-rivers", "amount": {"amount": 1234567, "currency": "NGN"}, "document_url": "https://files.sandbox.droomwork.com/example", "attested_by": ["usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]})import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/receipts',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "authority_reference": "paye-2026-09-rivers", "amount": {"amount": 1234567, "currency": "NGN"}, "document_url": "https://files.sandbox.droomwork.com/example", "attested_by": ["usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReceiptsCreate($idempotencyKey, json_decode('{"leg_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authority_reference":"paye-2026-09-rivers","amount":{"amount":1234567,"currency":"NGN"},"document_url":"https://files.sandbox.droomwork.com/example","attested_by":["usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]}', true));<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/receipts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"leg_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","authority_reference":"paye-2026-09-rivers","amount":{"amount":1234567,"currency":"NGN"},"document_url":"https://files.sandbox.droomwork.com/example","attested_by":["usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"]}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReceiptsCreate(idempotencyKey, body);var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/receipts"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"document_url": "https://files.sandbox.droomwork.com/example",
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReceiptsCreate(idempotencyKey, body);using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/receipts");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"document_url": "https://files.sandbox.droomwork.com/example",
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReceiptsCreate(ctx).IdempotencyKey(key).RemitReceiptCreateRequest(body).Execute()body := strings.NewReader(`{
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"document_url": "https://files.sandbox.droomwork.com/example",
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
]
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/receipts", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_receipt",
"livemode": true,
"mocked": true,
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"evidence_class": "authority_api_receipt",
"hash": "sha256:9f2c1e0043a1b8",
"previous_hash": "sha256:9f2c1e0043a1b8",
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"obligation_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"document_url": "https://files.sandbox.droomwork.com/example",
"trace_references": [
"paye-2026-09-rivers"
],
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
],
"vaulted_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/receipts/{receipt_id}#Retrieve a receipt
remittance.receipts.retrieve
You get the receipt with its hash chain position. There is no update and no delete; a receipt is never changed once vaulted.
Path parameters
receipt_id
string
requiredThe receipt's identifier: the id of a receipt listed at GET /v1/remittance/receipts or recorded at POST /v1/remittance/receipts, or the receipt_id on a leg. It starts with remit_authority_rail_receipt_.
Returns
The receipt.
id
string
requiredThe receipt's identifier, starting with remit_authority_rail_receipt_; it never changes. It is the receipt_id on the leg it proves and in receipt_ids on its obligation; pass it as receipt_id to GET /v1/remittance/receipts/{receipt_id}.
object
always "remittance_receipt"
requiredAlways remittance_receipt. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
leg_id
string · nullable
optionalThe id of the leg this receipt proves paid, from legs on a remittance or GET /v1/remittance/remittances/{remittance_id}/legs; vaulting the receipt takes that leg to completed. null when the receipt is not tied to a leg.
obligation_id
string · nullable
optionalThe id of the obligation this receipt settles against, from GET /v1/remittance/obligations, starting with remit_authority_rail_obligation_; the receipt also appears in its receipt_ids. null when not tied to an obligation.
authority_id
string
requiredThe id of the authority that issued this receipt, from GET /v1/remittance/authorities, starting with remit_authority_rail_obligation_; filter the list by it. It must agree with the leg's authority_id, or the receipt is quarantined.
period
string
requiredThe month the payment covers, as YYYY-MM, such as 2026-09; filter the list by it with the period query. It must agree with the leg's period, or the receipt is quarantined.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
authority_reference
string
optionalThe reference the authority itself issued.
evidence_class
string
requiredThe same classes apply whichever tier filed. An assisted manual filing carries a receipt reference, a document scan and an operator attestation under dual control, which is the same evidence class as an API filing.
authority_api_receiptportal_receiptassisted_manual_attesteddocument_url
string · uri · nullable
optionalWhere to fetch the receipt document the authority issued, as a URL. Present for an assisted manual filing, where you supplied the scan; null when there is no document.
hash
string
requiredThis receipt position in the append only chain.
previous_hash
string
requiredThe hash of the receipt vaulted just before this one. Each receipt carries the last one's hash, so you can walk the chain back and confirm nothing was changed or removed.
trace_references
array of string
optionalThe payroll trace references this receipt covers.
attested_by
array of string
optionalTwo actors for an assisted manual filing, under dual control.
vaulted_at
string · date-time
optionalWhen the receipt was hash chained into the vault, as an RFC 3339 timestamp in UTC. From this moment it never changes, and the leg it belongs to can reach completed.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReceiptsRetrieve({ receiptId: 'remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_receipts_retrieve(receipt_id='remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReceiptsRetrieve(receipt_id: 'remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReceiptsRetrieve("remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReceiptsRetrieve(receiptId: "remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReceiptsRetrieve(ctx, "remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/receipts/remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_receipt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_receipt",
"livemode": true,
"mocked": true,
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"evidence_class": "authority_api_receipt",
"hash": "sha256:9f2c1e0043a1b8",
"previous_hash": "sha256:9f2c1e0043a1b8",
"leg_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"obligation_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_reference": "paye-2026-09-rivers",
"document_url": "https://files.sandbox.droomwork.com/example",
"trace_references": [
"paye-2026-09-rivers"
],
"attested_by": [
"usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
],
"vaulted_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/audit_exports#Produce an audit pack
remittance.audit_exports.create
Name a period, an authority or an employee. The pack carries its own signature, so whoever receives it can verify it without trusting where it came from.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body
period
string
optionalScope the pack to one month, as YYYY-MM, such as 2026-09: every receipt for that period goes in. Send this, authority_id or subject_id, and only one of them.
authority_id
string
optionalScope the pack to one authority, by its id from GET /v1/remittance/authorities, starting with remit_authority_rail_obligation_: every receipt filed with it goes in. Send this, period or subject_id, and only one of them.
subject_id
string
optionalScope the pack to one employee, by their subject identifier starting with sub_, the subject_id on their payslips at GET /v1/payroll/payslips: every receipt covering them goes in. Send this, period or authority_id, and only one of them.
Returns
The export.
id
string
requiredThe pack's identifier, first returned by POST /v1/remittance/audit_exports; it starts with remit_authority_rail_return_ and never changes. Pass it as audit_export_id to GET /v1/remittance/audit_exports/{audit_export_id} to poll the pack.
object
always "audit_export"
requiredAlways audit_export. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredgenerating while the pack is being built, ready once it can be downloaded and verified, failed when it could not be produced. Poll GET /v1/remittance/audit_exports/{audit_export_id} until it leaves generating.
generatingreadyfailedscope
object
requiredWhat the pack covers, as the one scope you named when you asked for it: a period, an authority_id or a subject_id. The other two are null.
3 fields
period
string · nullable
optionalThe month the pack covers, as YYYY-MM, when you scoped it by period. null when you scoped it by authority or by employee.
authority_id
string · nullable
optionalThe authority the pack covers, when you scoped it by authority: the authority_id you sent to POST /v1/remittance/audit_exports, an id from GET /v1/remittance/authorities. null when you scoped it by period or by employee.
subject_id
string · nullable
optionalThe employee the pack covers, when you scoped it by employee: the subject_id you sent to POST /v1/remittance/audit_exports, their subject identifier starting with sub_. null when you scoped it by period or by authority.
download_url
string · uri · nullable
optionalWhere to fetch the pack, as a URL, once status is ready; null before then and when the pack failed. Verify what you download against signature.
signature
string · nullable
optionalVerify the pack against this without trusting the system that made it.
verification_instructions_url
string · uri · nullable
optionalWhere to read how to check the pack against its signature, as a URL; null until the pack is ready. Hand it on with the pack, so whoever receives it can verify it without trusting where it came from.
receipt_count
integer
optionalHow many vaulted receipts the pack holds for the scope you named. Compare it with your own count before you send the pack on; 0 means nothing was vaulted in that scope.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/audit_exports" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"period":"2026-09","authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","subject_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceAuditExportsCreate({
idempotencyKey: crypto.randomUUID(),
remitAuditExportCreateRequest: {"period":"2026-09","authorityId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","subjectId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"},
});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/audit_exports', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"period": "2026-09",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_audit_exports_create(body={"period": "2026-09", "authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"})import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/audit_exports',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"period": "2026-09", "authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceAuditExportsCreate($idempotencyKey, json_decode('{"period":"2026-09","authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","subject_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"}', true));<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/audit_exports');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"period":"2026-09","authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","subject_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceAuditExportsCreate(idempotencyKey, body);var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/audit_exports"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"period": "2026-09",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceAuditExportsCreate(idempotencyKey, body);using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/audit_exports");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"period": "2026-09",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceAuditExportsCreate(ctx).IdempotencyKey(key).RemitAuditExportCreateRequest(body).Execute()body := strings.NewReader(`{
"period": "2026-09",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/audit_exports", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "audit_export",
"livemode": true,
"mocked": true,
"status": "generating",
"scope": {
"period": "2026-09",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
},
"download_url": "https://files.sandbox.droomwork.com/example",
"signature": "example",
"verification_instructions_url": "https://files.sandbox.droomwork.com/example",
"receipt_count": 1
}
/v1/remittance/audit_exports/{audit_export_id}#Retrieve an audit pack
remittance.audit_exports.retrieve
You get the pack with the instructions for verifying its signature.
Path parameters
audit_export_id
string
requiredThe pack's identifier: the id of a pack you asked for at POST /v1/remittance/audit_exports. It starts with remit_authority_rail_return_; poll it here until status leaves generating.
Returns
The export.
id
string
requiredThe pack's identifier, first returned by POST /v1/remittance/audit_exports; it starts with remit_authority_rail_return_ and never changes. Pass it as audit_export_id to GET /v1/remittance/audit_exports/{audit_export_id} to poll the pack.
object
always "audit_export"
requiredAlways audit_export. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredgenerating while the pack is being built, ready once it can be downloaded and verified, failed when it could not be produced. Poll GET /v1/remittance/audit_exports/{audit_export_id} until it leaves generating.
generatingreadyfailedscope
object
requiredWhat the pack covers, as the one scope you named when you asked for it: a period, an authority_id or a subject_id. The other two are null.
3 fields
period
string · nullable
optionalThe month the pack covers, as YYYY-MM, when you scoped it by period. null when you scoped it by authority or by employee.
authority_id
string · nullable
optionalThe authority the pack covers, when you scoped it by authority: the authority_id you sent to POST /v1/remittance/audit_exports, an id from GET /v1/remittance/authorities. null when you scoped it by period or by employee.
subject_id
string · nullable
optionalThe employee the pack covers, when you scoped it by employee: the subject_id you sent to POST /v1/remittance/audit_exports, their subject identifier starting with sub_. null when you scoped it by period or by authority.
download_url
string · uri · nullable
optionalWhere to fetch the pack, as a URL, once status is ready; null before then and when the pack failed. Verify what you download against signature.
signature
string · nullable
optionalVerify the pack against this without trusting the system that made it.
verification_instructions_url
string · uri · nullable
optionalWhere to read how to check the pack against its signature, as a URL; null until the pack is ready. Hand it on with the pack, so whoever receives it can verify it without trusting where it came from.
receipt_count
integer
optionalHow many vaulted receipts the pack holds for the scope you named. Compare it with your own count before you send the pack on; 0 means nothing was vaulted in that scope.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceAuditExportsRetrieve({ auditExportId: '{audit_export_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_audit_exports_retrieve(audit_export_id='{audit_export_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceAuditExportsRetrieve(audit_export_id: '{audit_export_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceAuditExportsRetrieve("{audit_export_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceAuditExportsRetrieve(auditExportId: "{audit_export_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceAuditExportsRetrieve(ctx, "{audit_export_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/audit_exports/%7Baudit_export_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "audit_export",
"livemode": true,
"mocked": true,
"status": "generating",
"scope": {
"period": "2026-09",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"subject_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
},
"download_url": "https://files.sandbox.droomwork.com/example",
"signature": "example",
"verification_instructions_url": "https://files.sandbox.droomwork.com/example",
"receipt_count": 1
}
/v1/remittance/reconciliations#List daily reconciliations
remittance.reconciliations.list
Your statutory funds move through ring fenced accounts. This is your daily proof that every kobo debited is a kobo credited and that nothing is commingled.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
on
string
optionalReturn only the reconciliation for one day, as YYYY-MM-DD, such as 2026-09-01: the on each reconciliation carries. Leave it out to get every day.
Returns
A page of reconciliations.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of Reconciliation
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
9 fields of Reconciliation
id
string
requiredThe reconciliation's identifier, as listed at GET /v1/remittance/reconciliations; it starts with remit_authority_rail_return_ and never changes. Pass it as reconciliation_id to GET /v1/remittance/reconciliations/{reconciliation_id}.
object
always "reconciliation"
requiredAlways reconciliation. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
on
string · date
requiredThe day this reconciliation is for, as YYYY-MM-DD, such as 2026-09-01. One is produced for every day; filter the list by it with the on query.
balanced
boolean
requiredEvery kobo debited is a kobo credited, with no commingling.
opening_balance
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
closing_balance
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
breaks
array of object
requiredEmpty when balanced is true.
3 fields
code
string
requiredWhich kind of break this is, as a code you can match on, such as no_payee_destination. detail says what it means in words.
detail
string
requiredWhat went wrong, in words for a person to read, such as The payee has no verified destination, so this line cannot be paid. Match on code rather than on this text.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), on (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), on (optional)
const result = await api.remittanceReconciliationsList({ limit: 25, on: 'Tue Sep 01 2026 01:00:00 GMT+0100 (West Africa Time)' });// query parameters: limit (optional), on (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), on (optional)
result = api.remittance_reconciliations_list(limit=25, on='Tue Sep 01 2026 01:00:00 GMT+0100 (West Africa Time)')import os
import requests
# query parameters: limit (optional), on (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), on (optional)
$result = $api->remittanceReconciliationsList(limit: 25, on: 'Tue Sep 01 2026 01:00:00 GMT+0100 (West Africa Time)');<?php
// query parameters: limit (optional), on (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), on (optional)
var result = api.remittanceReconciliationsList(25, "Tue Sep 01 2026 01:00:00 GMT+0100 (West Africa Time)");// query parameters: limit (optional), on (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), on (optional)
var result = api.RemittanceReconciliationsList(limit: 25, on: "Tue Sep 01 2026 01:00:00 GMT+0100 (West Africa Time)");// query parameters: limit (optional), on (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), on (optional)
result, _, err := client.REMITAPI.RemittanceReconciliationsList(ctx).Limit(25).On("Tue Sep 01 2026 01:00:00 GMT+0100 (West Africa Time)").Execute()// query parameters: limit (optional), on (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/reconciliations?limit=25&on=Tue%20Sep%2001%202026%2001%3A00%3A00%20GMT%2B0100%20(West%20Africa%20Time)", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "reconciliation",
"livemode": true,
"mocked": true,
"on": "2026-09-01",
"balanced": true,
"breaks": [
{
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid.",
"amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"opening_balance": {
"amount": 1234567,
"currency": "NGN"
},
"closing_balance": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"has_more": true
}
/v1/remittance/reconciliations/{reconciliation_id}#Retrieve a reconciliation
remittance.reconciliations.retrieve
You get the day with every break found, if any.
Path parameters
reconciliation_id
string
requiredThe reconciliation's identifier: the id of a reconciliation listed at GET /v1/remittance/reconciliations, starting with remit_authority_rail_return_. Each one is a day's proof that every kobo debited was a kobo credited.
Returns
The reconciliation.
id
string
requiredThe reconciliation's identifier, as listed at GET /v1/remittance/reconciliations; it starts with remit_authority_rail_return_ and never changes. Pass it as reconciliation_id to GET /v1/remittance/reconciliations/{reconciliation_id}.
object
always "reconciliation"
requiredAlways reconciliation. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
on
string · date
requiredThe day this reconciliation is for, as YYYY-MM-DD, such as 2026-09-01. One is produced for every day; filter the list by it with the on query.
balanced
boolean
requiredEvery kobo debited is a kobo credited, with no commingling.
opening_balance
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
closing_balance
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
breaks
array of object
requiredEmpty when balanced is true.
3 fields
code
string
requiredWhich kind of break this is, as a code you can match on, such as no_payee_destination. detail says what it means in words.
detail
string
requiredWhat went wrong, in words for a person to read, such as The payee has no verified destination, so this line cannot be paid. Match on code rather than on this text.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReconciliationsRetrieve({ reconciliationId: '{reconciliation_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_reconciliations_retrieve(reconciliation_id='{reconciliation_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReconciliationsRetrieve(reconciliation_id: '{reconciliation_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReconciliationsRetrieve("{reconciliation_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReconciliationsRetrieve(reconciliationId: "{reconciliation_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReconciliationsRetrieve(ctx, "{reconciliation_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/reconciliations/%7Breconciliation_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "reconciliation",
"livemode": true,
"mocked": true,
"on": "2026-09-01",
"balanced": true,
"breaks": [
{
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid.",
"amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"opening_balance": {
"amount": 1234567,
"currency": "NGN"
},
"closing_balance": {
"amount": 1234567,
"currency": "NGN"
}
}
/v1/remittance/returns#List employer returns
remittance.returns.list
Lists the filings you owe each authority, not the payments.
Query parameters
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
status
string
optionalRestricts the list to returns in one state: draft or pending_approval (not yet approved), approved, submitted (filed), accepted or rejected (the authority's answer). Leave it out to get every return.
draftpending_approvalapprovedsubmittedacceptedrejectedReturns
A page of returns.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of EmployerReturn
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
13 fields of EmployerReturn
id
string
requiredThe return's identifier, first given by POST /v1/remittance/returns and on every record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_ and never changes; pass it as return_id to retrieve, approve or submit.
object
always "employer_return"
requiredAlways employer_return. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
kind
string
requiredmonthly_payeannual_payepension_schedulenhf_schedulensitf_returnitf_returnnhia_schedulestatus
string
requireddraftpending_approvalapprovedsubmittedacceptedrejectedauthority_id
string
requiredThe authority this return is filed with: the id of an authority from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. It is the authority_id you sent when you generated the return.
period
string
requiredThe period the return covers, as you named it: YYYY-MM for a month, YYYY for a whole year. For example 2026-09.
generated_from
array of string
optionalThe vaulted receipts this return was generated from.
totals
object
optionalWhat the return declares, summed from the vaulted receipts it was generated from: how many employees and the total amount.
2 fields
employee_count
integer
optionalHow many employees the return declares for the period.
total
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
approved_by
string · nullable
optionalA named person. Required before submission.
submitted_at
string · date-time · nullable
optionalWhen the return was filed with the authority, as an RFC 3339 timestamp in UTC. null until you submit it.
authority_reference
string · nullable
optionalThe reference the authority gave your filing, such as paye-2026-09-rivers. null until the authority has issued one.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: limit (optional), starting_after (optional), status (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: limit (optional), starting_after (optional), status (optional)
const result = await api.remittanceReturnsList({ limit: 25, status: 'draft' });// query parameters: limit (optional), starting_after (optional), status (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: limit (optional), starting_after (optional), status (optional)
result = api.remittance_returns_list(limit=25, status='draft')import os
import requests
# query parameters: limit (optional), starting_after (optional), status (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: limit (optional), starting_after (optional), status (optional)
$result = $api->remittanceReturnsList(limit: 25, status: 'draft');<?php
// query parameters: limit (optional), starting_after (optional), status (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
import com.droomwork.sdk.model.*;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: limit (optional), starting_after (optional), status (optional)
var result = api.remittanceReturnsList(25, null, RemitReturnStatus.fromValue("draft"));// query parameters: limit (optional), starting_after (optional), status (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: limit (optional), starting_after (optional), status (optional)
var result = api.RemittanceReturnsList(limit: 25, status: RemitReturnStatus.Draft);// query parameters: limit (optional), starting_after (optional), status (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: limit (optional), starting_after (optional), status (optional)
result, _, err := client.REMITAPI.RemittanceReturnsList(ctx).Limit(25).Status(droomwork.RemitReturnStatus("draft")).Execute()// query parameters: limit (optional), starting_after (optional), status (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/returns?limit=25&status=draft", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "employer_return",
"livemode": true,
"mocked": true,
"kind": "monthly_paye",
"status": "draft",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"generated_from": [
"example"
],
"totals": {
"employee_count": 1,
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"submitted_at": "2026-09-01T09:00:00Z",
"authority_reference": "paye-2026-09-rivers"
}
],
"has_more": true
}
/v1/remittance/returns#Generate an employer return
remittance.returns.create
Name the period and the authority, not the numbers. The return is generated from vaulted receipts, so it and the receipts behind it cannot disagree.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Body
kind
string
requiredmonthly_payeannual_payepension_schedulenhf_schedulensitf_returnitf_returnnhia_scheduleauthority_id
string
requiredThe authority to file with: the id of an authority from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. The return is generated from your vaulted receipts for that authority.
period
string
requiredThe period to file for, as YYYY-MM for a month or YYYY for a whole year, such as 2026-09. The figures come from your vaulted receipts for that period, not from you.
Returns
The generated return, awaiting approval.
id
string
requiredThe return's identifier, first given by POST /v1/remittance/returns and on every record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_ and never changes; pass it as return_id to retrieve, approve or submit.
object
always "employer_return"
requiredAlways employer_return. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
kind
string
requiredmonthly_payeannual_payepension_schedulenhf_schedulensitf_returnitf_returnnhia_schedulestatus
string
requireddraftpending_approvalapprovedsubmittedacceptedrejectedauthority_id
string
requiredThe authority this return is filed with: the id of an authority from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. It is the authority_id you sent when you generated the return.
period
string
requiredThe period the return covers, as you named it: YYYY-MM for a month, YYYY for a whole year. For example 2026-09.
generated_from
array of string
optionalThe vaulted receipts this return was generated from.
totals
object
optionalWhat the return declares, summed from the vaulted receipts it was generated from: how many employees and the total amount.
2 fields
employee_count
integer
optionalHow many employees the return declares for the period.
total
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
approved_by
string · nullable
optionalA named person. Required before submission.
submitted_at
string · date-time · nullable
optionalWhen the return was filed with the authority, as an RFC 3339 timestamp in UTC. null until you submit it.
authority_reference
string · nullable
optionalThe reference the authority gave your filing, such as paye-2026-09-rivers. null until the authority has issued one.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/returns" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"kind":"monthly_paye","authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","period":"2026-09"}'import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReturnsCreate({
idempotencyKey: crypto.randomUUID(),
remitEmployerReturnCreateRequest: {"kind":"monthly_paye","authorityId":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","period":"2026-09"},
});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/returns', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
"kind": "monthly_paye",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09"
}),
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_returns_create(body={"kind": "monthly_paye", "authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "period": "2026-09"})import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/returns',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
json={"kind": "monthly_paye", "authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "period": "2026-09"},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReturnsCreate($idempotencyKey, json_decode('{"kind":"monthly_paye","authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","period":"2026-09"}', true));<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/returns');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
CURLOPT_POSTFIELDS => '{"kind":"monthly_paye","authority_id":"sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z","period":"2026-09"}',
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReturnsCreate(idempotencyKey, body);var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/returns"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Content-Type", "application/json")
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.ofString("""
{
"kind": "monthly_paye",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09"
}
"""))
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReturnsCreate(idempotencyKey, body);using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/returns");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
request.Content = new StringContent("""
{
"kind": "monthly_paye",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09"
}
""", Encoding.UTF8, "application/json");
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReturnsCreate(ctx).IdempotencyKey(key).RemitEmployerReturnCreateRequest(body).Execute()body := strings.NewReader(`{
"kind": "monthly_paye",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09"
}`)
req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/returns", body)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "employer_return",
"livemode": true,
"mocked": true,
"kind": "monthly_paye",
"status": "draft",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"generated_from": [
"example"
],
"totals": {
"employee_count": 1,
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"submitted_at": "2026-09-01T09:00:00Z",
"authority_reference": "paye-2026-09-rivers"
}
/v1/remittance/returns/{return_id}#Retrieve an employer return
remittance.returns.retrieve
You get the filing with the vaulted facts it was generated from.
Path parameters
return_id
string
requiredThe return's identifier: the id on the return POST /v1/remittance/returns gave you, or on any record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_.
Returns
The return.
id
string
requiredThe return's identifier, first given by POST /v1/remittance/returns and on every record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_ and never changes; pass it as return_id to retrieve, approve or submit.
object
always "employer_return"
requiredAlways employer_return. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
kind
string
requiredmonthly_payeannual_payepension_schedulenhf_schedulensitf_returnitf_returnnhia_schedulestatus
string
requireddraftpending_approvalapprovedsubmittedacceptedrejectedauthority_id
string
requiredThe authority this return is filed with: the id of an authority from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. It is the authority_id you sent when you generated the return.
period
string
requiredThe period the return covers, as you named it: YYYY-MM for a month, YYYY for a whole year. For example 2026-09.
generated_from
array of string
optionalThe vaulted receipts this return was generated from.
totals
object
optionalWhat the return declares, summed from the vaulted receipts it was generated from: how many employees and the total amount.
2 fields
employee_count
integer
optionalHow many employees the return declares for the period.
total
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
approved_by
string · nullable
optionalA named person. Required before submission.
submitted_at
string · date-time · nullable
optionalWhen the return was filed with the authority, as an RFC 3339 timestamp in UTC. null until you submit it.
authority_reference
string · nullable
optionalThe reference the authority gave your filing, such as paye-2026-09-rivers. null until the authority has issued one.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReturnsRetrieve({ returnId: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_returns_retrieve(return_id='remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReturnsRetrieve(return_id: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReturnsRetrieve("remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReturnsRetrieve(returnId: "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReturnsRetrieve(ctx, "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "employer_return",
"livemode": true,
"mocked": true,
"kind": "monthly_paye",
"status": "draft",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"generated_from": [
"example"
],
"totals": {
"employee_count": 1,
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"submitted_at": "2026-09-01T09:00:00Z",
"authority_reference": "paye-2026-09-rivers"
}
/v1/remittance/returns/{return_id}/approve#Approve a return for submission
remittance.returns.approve
A named person approves before anything is filed. Approval records who; submission records when.
Path parameters
return_id
string
requiredThe return's identifier: the id on the return POST /v1/remittance/returns gave you, or on any record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
The approved return.
id
string
requiredThe return's identifier, first given by POST /v1/remittance/returns and on every record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_ and never changes; pass it as return_id to retrieve, approve or submit.
object
always "employer_return"
requiredAlways employer_return. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
kind
string
requiredmonthly_payeannual_payepension_schedulenhf_schedulensitf_returnitf_returnnhia_schedulestatus
string
requireddraftpending_approvalapprovedsubmittedacceptedrejectedauthority_id
string
requiredThe authority this return is filed with: the id of an authority from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. It is the authority_id you sent when you generated the return.
period
string
requiredThe period the return covers, as you named it: YYYY-MM for a month, YYYY for a whole year. For example 2026-09.
generated_from
array of string
optionalThe vaulted receipts this return was generated from.
totals
object
optionalWhat the return declares, summed from the vaulted receipts it was generated from: how many employees and the total amount.
2 fields
employee_count
integer
optionalHow many employees the return declares for the period.
total
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
approved_by
string · nullable
optionalA named person. Required before submission.
submitted_at
string · date-time · nullable
optionalWhen the return was filed with the authority, as an RFC 3339 timestamp in UTC. null until you submit it.
authority_reference
string · nullable
optionalThe reference the authority gave your filing, such as paye-2026-09-rivers. null until the authority has issued one.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReturnsApprove({ returnId: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_returns_approve(return_id='remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReturnsApprove(return_id: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReturnsApprove("remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReturnsApprove(returnId: "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReturnsApprove(ctx, "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/approve", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "employer_return",
"livemode": true,
"mocked": true,
"kind": "monthly_paye",
"status": "draft",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"generated_from": [
"example"
],
"totals": {
"employee_count": 1,
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"submitted_at": "2026-09-01T09:00:00Z",
"authority_reference": "paye-2026-09-rivers"
}
/v1/remittance/returns/{return_id}/submit#Submit an approved return to the authority
remittance.returns.submit
Files the return with the authority. Refused unless a named person has approved it.
Path parameters
return_id
string
requiredThe return's identifier: the id on the return POST /v1/remittance/returns gave you, or on any record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
Submission accepted.
id
string
requiredThe return's identifier, first given by POST /v1/remittance/returns and on every record of GET /v1/remittance/returns. It starts with remit_authority_rail_return_ and never changes; pass it as return_id to retrieve, approve or submit.
object
always "employer_return"
requiredAlways employer_return. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
kind
string
requiredmonthly_payeannual_payepension_schedulenhf_schedulensitf_returnitf_returnnhia_schedulestatus
string
requireddraftpending_approvalapprovedsubmittedacceptedrejectedauthority_id
string
requiredThe authority this return is filed with: the id of an authority from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. It is the authority_id you sent when you generated the return.
period
string
requiredThe period the return covers, as you named it: YYYY-MM for a month, YYYY for a whole year. For example 2026-09.
generated_from
array of string
optionalThe vaulted receipts this return was generated from.
totals
object
optionalWhat the return declares, summed from the vaulted receipts it was generated from: how many employees and the total amount.
2 fields
employee_count
integer
optionalHow many employees the return declares for the period.
total
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
approved_by
string · nullable
optionalA named person. Required before submission.
submitted_at
string · date-time · nullable
optionalWhen the return was filed with the authority, as an RFC 3339 timestamp in UTC. null until you submit it.
authority_reference
string · nullable
optionalThe reference the authority gave your filing, such as paye-2026-09-rivers. null until the authority has issued one.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReturnsSubmit({ returnId: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_returns_submit(return_id='remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReturnsSubmit(return_id: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReturnsSubmit("remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReturnsSubmit(returnId: "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReturnsSubmit(ctx, "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/returns/remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/submit", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "employer_return",
"livemode": true,
"mocked": true,
"kind": "monthly_paye",
"status": "draft",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"period": "2026-09",
"generated_from": [
"example"
],
"totals": {
"employee_count": 1,
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"submitted_at": "2026-09-01T09:00:00Z",
"authority_reference": "paye-2026-09-rivers"
}
/v1/remittance/readiness#What REMIT needs, what you have, and what is missing
remittance.readiness.retrieve
Tells you whether instruction sets are arriving from Droomwork payroll or being supplied by you, and which authorities you hold credentials for.
Call it before your first filing rather than discover a missing credential on a deadline.
Returns
The readiness report.
object
always "readiness_report"
requiredAlways readiness_report. Tells you which kind of record you are looking at, so one handler can read any response.
module
string
requiredThe module whose readiness endpoint you called, such as GET /v1/payroll/readiness: anchor (identity), proof (credentials), rail (engagements), flow (sourcing), match (allocation), run (payroll), remit (remittance) or route (payouts).
anchorproofrailflowmatchrunremitroutemode
string
requiredintegrated means a required fact comes from the Droomwork module that owns it; standalone means you supply it yourself under an attestation. The checks are the same in both, and what each fact is worth is recorded on its row as held.
integratedstandaloneready
boolean
requiredtrue when every row is satisfied and the module has what it needs from you. false when a required fact is missing or held at too low an assurance; rows says which.
rows
array of ReadinessRow
requiredOne row per fact the module requires: who owns it, the assurance it needs, what you hold and whether that satisfies it. The rows that are not satisfied are what to bring.
8 fields of ReadinessRow
fact
string
requiredNamed for what it is, not for who supplies it.
owner
string
requiredThe sibling module that owns this fact when running integrated.
contract_row
string
optionalrequired
string
requiredHow a fact was established. Recorded on the fact rather than in configuration, so an attested identity and a verified one stay distinguishable a year later, which is the distinction that matters when something is disputed.
attestedverifiedheld
one of
requiredAssuranceorsource
string · nullable
optionalintegratedstandalonenullsatisfied
boolean
requiredmissing_because
string · nullable
optionalnot_suppliedassurance_too_lownullalways_enforced
array of string
optionalGates that hold in every mode and cannot be attested away. Consent before any source is queried, bank account validation, the tax identifiers returns are filed under, and duplicate detection within the organisation's own population.
authorities_without_credentials
array of string
optionalFiling cannot proceed for these until credentials are supplied.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/readiness" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceReadinessRetrieve({});const response = await fetch('https://sandbox.droomwork.io/v1/remittance/readiness', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_readiness_retrieve()import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/readiness',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceReadinessRetrieve();<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/readiness');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceReadinessRetrieve();var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/readiness"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceReadinessRetrieve();using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/readiness");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceReadinessRetrieve(ctx).Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/readiness", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "readiness_report",
"module": "anchor",
"mode": "integrated",
"ready": true,
"rows": [
{
"fact": "anchored_subject",
"owner": "anchor",
"required": "attested",
"held": "attested",
"satisfied": true,
"contract_row": "6.1.13",
"source": "integrated",
"missing_because": "not_supplied"
}
],
"always_enforced": [
"example"
],
"authorities_without_credentials": [
"example"
]
}
/v1/remittance/instruction_sets/{instruction_set_id}/reject#Reject an ingested instruction set
remittance.instruction_sets.reject
The counterpart of accept. A rejected set is never remitted against and never silently corrected: whoever submitted it submits a new one. Refused unless the set is pending acceptance; a set already accepted has obligations standing against it.
Path parameters
instruction_set_id
string
requiredThe set's identifier: the id returned by POST /v1/remittance/instruction_sets or listed at GET /v1/remittance/instruction_sets, or an import's instruction_set_id. It starts with remit_authority_rail_instruction_.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
The rejected instruction set.
id
string
requiredThe set's identifier, starting remit_authority_rail_instruction_, as listed at GET /v1/remittance/instruction_sets. It never changes; pass it as instruction_set_id to retrieve, accept, reject or remit the set.
object
always "ingested_instruction_set"
requiredAlways ingested_instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requiredNothing is committed until accepted.
receivedvalidatingpending_acceptanceacceptedrejectedsource
string
requiredWhere the set came from. Droomwork payroll or your own, by API or by file. Everything downstream behaves identically whichever it was.
runexternal_apiexternal_fileperiod
string
requiredThe month the set covers, as YYYY-MM, such as 2026-09. Filter the list by it with the period query.
run_id
string · nullable
optionalThe Droomwork payroll run the set came from, by its id from POST /v1/payroll/runs or GET /v1/payroll/runs, starting run_enterprise_. Present when source is run; null when the set came from your own payroll.
instructions
InstructionSet
optionalWhat is owed to whom for one run. This shape is owned jointly by RUN and REMIT. RUN row 19 emits it and REMIT row 1 ingests it, from RUN and from external payroll alike. It lives here rather than in either module document so the two cannot drift, which is the failure that would otherwise surface at M3 with RUN already accepted and paid. Totals reconcile to run totals to the kobo, because they sum payslip lines rather than recompute from an aggregate. This is the object REMIT ingests.
11 fields of InstructionSet
id
string
requiredThe instruction set's identifier, which never changes: read it at GET /v1/payroll/runs/{run_id}/instruction_set when Droomwork ran the payroll, and send the set on unchanged to POST /v1/remittance/instruction_sets. Quote it when you ask about the set.
object
always "instruction_set"
requiredAlways instruction_set. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
run_id
string
requiredThe payroll run this set is owed for, by its id from POST /v1/payroll/runs, which starts with run_enterprise_. The set's totals reconcile to that run's totals to the kobo.
period
string
optionalThe pay period the amounts are owed for, as year and month, for example 2026-09.
paye
array of object
requiredGrouped by the State IRS of the employee's residence, not the employer's location.
5 fields
authority_id
string
requiredThe State Internal Revenue Service this PAYE is owed to, by its id from GET /v1/remittance/authorities, which starts with remit_authority_rail_obligation_. Use it wherever a call names the authority.
jurisdiction
string
requiredThe State Internal Revenue Service this line is grouped under, named in full, for example Rivers State Internal Revenue Service. Read it to label the line; authority_id names the authority in a call.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
payee_count
integer
optionalHow many employees this line's PAYE covers. Optional; when it is present, check it against your own headcount for that state.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it, for example paye-2026-09-rivers. Keep it with your own records so you can trace the line later.
pension
array of object
requiredGrouped by administrator and retirement savings account number.
6 fields
administrator_id
string
requiredThe Pension Fund Administrator these contributions are owed to, by its id from GET /v1/remittance/authorities with kind=pension_administrator, which starts with remit_authority_rail_obligation_. Use it wherever a call names the administrator.
administrator_name
string
optionalThe administrator's name in full, so you can label the line without a second call. Optional; administrator_id is what names the administrator in a call.
employee_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
employer_amount
Money
optional2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
amount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this line when you reconcile it. Keep it with your own records so you can trace the line later.
levies
array of object
requiredNHF, NSITF, ITF and NHIA totals, each with a reconciliation reference.
3 fields
code
string
requiredWhich levy this line is for: nhf the National Housing Fund, nsitf the Nigeria Social Insurance Trust Fund, itf the Industrial Training Fund, nhia the National Health Insurance Authority. One line per levy.
nhfnsitfitfnhiaamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
reconciliation_reference
string
requiredThe reference that identifies this levy line when you reconcile it. Keep it with your own records so you can trace the line later.
totals
object
requiredThe set's grand total, which its lines sum to. From a Droomwork run it reconciles to the run's totals to the kobo.
1 field
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
validation_report
ValidationReport
requiredThe result of checking a submission before anything is committed. Names every failing entry rather than stopping at the first, so one submission tells you everything to fix. The same shape wherever the platform ingests, validates and reports, which is every bulk intake in every module.
4 fields of ValidationReport
entry_count
integer · minimum 0
requiredHow many entries the submission held: every row in the file or line in the instruction set, whether it passed or not.
error_count
integer · minimum 0
requiredHow many entries failed with an error. Each is named in entries with its position and why, so one submission tells you everything to fix.
warning_count
integer · minimum 0
requiredHow many entries passed with a warning, each named in entries. A warning does not fail the entry; it points at something to confirm before you go ahead.
entries
array of object
optionalOne item per error or warning found, with the row or line it sits on, its severity, a code and what was wrong. Empty or absent when every entry passed clean.
4 fields
index
integer · minimum 1
requiredThe row in a file, or the line in an instruction set.
severity
string
requirederror means the entry failed and must be fixed. warning means it passed, but points at something you should confirm before you go ahead.
errorwarningcode
string
requiredWhy the entry was flagged, as a code you can branch on. detail says the same in words and may change; the code does not.
detail
string
requiredWhat was wrong with the entry, in plain words. Show it beside the row; it may change, so branch on code.
jurisdiction_pack
object
optionalThe jurisdiction pack the set is pinned to, by identifier and version. Every line was recomputed against it, so its rules are the ones the validation report reflects.
2 fields
pack_id
string
optionalWhich jurisdiction pack the set is pinned to, such as ng-paye. We publish the packs and you never send this; with version, it names exactly which rules every line was checked against, and it stays with the set so you can show which rules applied.
version
string
optionalThe pack version the set was checked against, such as 2026.08.1. It's pinned, so a later pack release doesn't change what this set was judged by.
accepted_by
string · nullable
optionalWho accepted the set: the actor that called accept. null until the set is accepted.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceInstructionSetsReject({ instructionSetId: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_instruction_sets_reject(instruction_set_id='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceInstructionSetsReject(instruction_set_id: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceInstructionSetsReject("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceInstructionSetsReject(instructionSetId: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceInstructionSetsReject(ctx, "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/instruction_sets/remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/reject", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "ingested_instruction_set",
"livemode": true,
"mocked": true,
"status": "received",
"source": "run",
"period": "2026-09",
"validation_report": {
"entry_count": 0,
"error_count": 0,
"warning_count": 0,
"entries": [
{
"index": 1,
"severity": "error",
"code": "no_payee_destination",
"detail": "The payee has no verified destination, so this line cannot be paid."
}
]
},
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"instructions": {
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "instruction_set",
"livemode": true,
"mocked": true,
"run_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"paye": [
{
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"jurisdiction": "Rivers State Internal Revenue Service",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"payee_count": 1
}
],
"pension": [
{
"administrator_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers",
"administrator_name": "Rivers State Internal Revenue Service",
"employee_amount": {
"amount": 1234567,
"currency": "NGN"
},
"employer_amount": {
"amount": 1234567,
"currency": "NGN"
}
}
],
"levies": [
{
"code": "nhf",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"reconciliation_reference": "paye-2026-09-rivers"
}
],
"totals": {
"total": {
"amount": 1234567,
"currency": "NGN"
}
},
"period": "2026-09",
"created_at": "2026-09-01T09:00:00Z"
},
"jurisdiction_pack": {
"pack_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"version": "2026.08.1"
},
"accepted_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/remittances/{remittance_id}/execute#Execute an approved remittance
remittance.remittances.execute
Runs every leg. A leg that fails leaves the others alone, so the remittance can come back partially completed rather than failed. Refused unless the remittance has been approved: approval is a person, and execution moves money.
Path parameters
remittance_id
string
requiredThe remittance's identifier: the id of a remittance you created at POST /v1/remittance/remittances or listed at GET /v1/remittance/remittances. It starts with remit_authority_rail_remittance_.
Headers
Idempotency-Key
string
requiredA key you make up for this request, such as a UUID, up to 255 characters. Sending the same key with the same body returns the original response, marked Droomwork-Idempotent-Replay: true; sending it with a different body is refused with idempotency_key_reused.
Returns
The remittance, executing.
id
string
requiredThe remittance's identifier, first returned by POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_ and never changes. Pass it as remittance_id wherever a call names this remittance.
object
always "remittance"
requiredAlways remittance. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm this record is in: false is the sandbox, true is live. Read it before you act on anything.
mocked
boolean
requiredWhere these figures came from: true when they were mocked, false when they were computed for real. Not the inverse of livemode: each record carries the answer that was true for it.
status
string
requireddraftapprovedexecutingcompletedpartially_completedfailedinstruction_set_id
string
requiredThe id of the accepted instruction set whose figures the legs pay, from POST /v1/remittance/instruction_sets, starting with remit_authority_rail_instruction_. Retrieve it at GET /v1/remittance/instruction_sets/{instruction_set_id}.
period
string
optionalThe month the remittance pays for, as YYYY-MM, such as 2026-09. It's the period of the instruction set it was created from.
total
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
legs
array of Leg
requiredOne leg per authority the remittance pays, each with its own state, amount and receipt. A leg runs on its own, so one authority being down never holds the others; read each to see what settled where.
11 fields of Leg
id
string
requiredThe leg's identifier, first returned in legs on the remittance from POST /v1/remittance/remittances; it never changes. Pass it as leg_id, with the remittance's id as remittance_id, to retrieve or retry the leg.
object
always "remittance_leg"
requiredAlways remittance_leg. Tells you which kind of record you are looking at, so one handler can read any response.
remittance_id
string
optionalThe id of the remittance this leg belongs to, from POST /v1/remittance/remittances; it starts with remit_authority_rail_remittance_. Every call that names the leg names it too, at /v1/remittance/remittances/{remittance_id}/legs/{leg_id}.
authority_id
string
requiredThe id of the authority this leg pays, as listed at GET /v1/remittance/authorities; it starts with remit_authority_rail_obligation_. Look it up at GET /v1/remittance/authorities/{authority_id} for its name, tier and capabilities.
authority_name
string
optionalThe authority's name as you'd write it, such as Rivers State Internal Revenue Service. For display; authority_id is what you match on.
tier
string
optionalHow the filing reaches the authority. Readable so you know what to expect on timing. Never something to code against, since all three present the same contract.
direct_apiportal_automationassisted_manualstatus
string
requiredA leg reaches completed only once its receipt is vaulted. quarantined means a receipt arrived but disagreed with the leg.
pendingexecutingawaiting_receiptcompletedquarantinedfailedamount
Money
required2 fields of Money
amount
integer · int64
requiredA whole number of the currency's minor unit, as defined by the ISO 4217 exponent. For NGN that is kobo, so 1234567 is twelve thousand three hundred and forty five naira and sixty seven kobo. A fractional value is refused with the code invalid_money_amount. Call GET /v1/currencies for the exponent of any currency. Never divide by a hundred by hand.
currency
string
requiredISO 4217 code.
receipt_id
string · nullable
optionalThe id of the receipt that is this leg's proof of payment, once vaulted; it starts with remit_authority_rail_receipt_ and you retrieve it at GET /v1/remittance/receipts/{receipt_id}. null until a receipt is vaulted.
attempts
integer · minimum 0
optionalHow many times filing this leg with its authority has been tried, retries included. 0 before the first try; read it with last_fault before you retry.
last_fault
string · nullable
optionalWhy the latest attempt failed, in words for a person to read, such as The register did not answer within the timeout. null when there is no fault to report; read it before you retry.
approved_by
string · nullable
optionalWho approved the remittance: the actor that called approve. null while it is still draft, and execution is refused until a person is named here.
created_at
string · date-time
optionalWhen the record was created, as an RFC 3339 timestamp in UTC.
Other responses
Errors it can return
curl -X POST "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceRemittancesExecute({ remittanceId: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute', {
method: 'POST',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
'Idempotency-Key': crypto.randomUUID(),
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_remittances_execute(remittance_id='remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z')import os
import uuid
import requests
response = requests.request(
'POST',
'https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
'Idempotency-Key': str(uuid.uuid4()),
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceRemittancesExecute(remittance_id: 'remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
'Idempotency-Key: ' . bin2hex(random_bytes(16)),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceRemittancesExecute("remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.header("Idempotency-Key", UUID.randomUUID().toString())
.method("POST", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceRemittancesExecute(remittanceId: "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
request.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceRemittancesExecute(ctx, "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Execute()req, _ := http.NewRequest("POST", "https://sandbox.droomwork.io/v1/remittance/remittances/remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z/execute", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
req.Header.Set("Idempotency-Key", uuid.NewString())
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "remit_authority_rail_remittance_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance",
"livemode": true,
"mocked": true,
"status": "draft",
"instruction_set_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"legs": [
{
"id": "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "remittance_leg",
"authority_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"status": "pending",
"amount": {
"amount": 1234567,
"currency": "NGN"
},
"remittance_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"authority_name": "Rivers State Internal Revenue Service",
"tier": "direct_api",
"receipt_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"attempts": 0,
"last_fault": "The register did not answer within the timeout."
}
],
"total": {
"amount": 1234567,
"currency": "NGN"
},
"period": "2026-09",
"approved_by": "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"created_at": "2026-09-01T09:00:00Z"
}
/v1/remittance/events#List events
remittance.events.list
The append only record of everything REMIT is the authority for, oldest first. Every event here is one the webhook catalogue declares, so the code that handles a delivery handles a replay too.
Two ways to read it. Pass stream with after to replay one stream from the sequence you last handled; that is exact and needs no cursor, because the sequence counts per organisation and per stream. Without stream, you get events across streams in the order they were recorded, paged with starting_after.
Query parameters
stream
string
optionalThe id of the record whose events you want, such as an instruction set's (remit_authority_rail_instruction_…, from POST /v1/remittance/instruction_sets) or a return's (remit_authority_rail_return_…). Omit it to get every record's events.
after
integer
optionalThe last sequence you handled on that record; you get the events after it, so 0 reads from the start. Send stream beside it, because a sequence counts within one record's events.
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
Returns
A page of events.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of StoredEvent
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
13 fields of StoredEvent
id
string
requiredThe event's identifier, starting with evt_, the same on a webhook delivery and on the module's events list, such as GET /v1/payroll/events. It never changes: a redelivery carries the same id, so you can recognise an event you have already handled.
type
string
requiredWhat happened, as module.resource.past_tense_verb, for example run.payslip.calculated. Pick your handler on it; data takes the shape this type promises.
schema_version
integer · minimum 1
requiredThe version of the shape data takes for this type, starting at 1. A change to the shape raises it, so check it before you read data.
org_id
string
requiredThe organisation the event belongs to, by its id, which starts with org_: the one POST /v1/registrations gave you and GET /v1/me returns. You only ever receive events for your own organisation.
sequence
integer · minimum 0
requiredPer organisation and per stream. It is how a consumer tells a replay from a new event, and it is what the delivery guarantee rests on.
occurred_at
string · date-time
requiredWhen the event happened, as an RFC 3339 timestamp in UTC. Not when it was delivered: a redelivery carries the original value.
request_id
string
optionalThe request that caused this event, where one did: the Droomwork-Request-Id that request returned, starting with req_. Absent for an event a schedule raised, such as an engagement lapsing on its end date.
livemode
boolean
requiredWhich realm the event happened in. False is the sandbox.
mocked
boolean
requiredWhether a mock produced this fact, rather than an engine computing it. Recorded on the event when it was appended and never worked out afterwards from the realm: the two answers agree while every module is on its mock and part on the day the first engine ships. See ADR-0011.
source
string
requiredWhich part of Droomwork is the authority for this fact: anchor (identity), proof (credentials), rail (engagements), flow (sourcing), match (allocation), run (payroll), remit (remittance), route (payouts), gateway (the API's front door), iam (accounts and API keys), ledger (the books), registry (rule packs), delivery (webhooks and messages), documents (rendered payslips and instruments) or intelligence (AI decisions). Read the fact from there when it matters; your own copy is never the authority.
anchorproofrailflowmatchrunremitroutegatewayiamledgerregistrydeliverydocumentsintelligenceobject
always "event"
requiredAlways event. Tells you which kind of record you are looking at, so one handler can read any response.
stream
string
requiredThe id of the record the event is about: an instruction set (remit_authority_rail_instruction_…), obligation, leg, receipt or return (remit_authority_rail_return_…). sequence counts within it; replay with both at GET /v1/remittance/events.
data
object
requiredThe record the event is about, as it stood when the event happened. Its shape follows type: an instruction set, an obligation, a leg, a receipt or an employer return.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
const result = await api.remittanceEventsList({ stream: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', after: 0, limit: 25 });// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
result = api.remittance_events_list(stream='remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', after=0, limit=25)import os
import requests
# query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
$result = $api->remittanceEventsList(stream: 'remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', after: 0, limit: 25);<?php
// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
var result = api.remittanceEventsList("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", 0, 25, null);// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
var result = api.RemittanceEventsList(stream: "remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", after: 0, limit: 25);// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
result, _, err := client.REMITAPI.RemittanceEventsList(ctx).Stream("remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").After(0).Limit(25).Execute()// query parameters: stream (optional), after (optional), limit (optional), starting_after (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/events?stream=remit_authority_rail_instruction_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&after=0&limit=25", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "evt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"type": "run.payslip.calculated",
"schema_version": 1,
"org_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"sequence": 0,
"occurred_at": "2026-09-01T09:00:00Z",
"livemode": true,
"mocked": true,
"source": "anchor",
"request_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "event",
"stream": "example",
"data": {}
}
],
"has_more": true
}
/v1/remittance/events/{event_id}#Retrieve an event
remittance.events.retrieve
You get one event. An identifier belonging to another organisation comes back not found rather than refused.
Path parameters
event_id
string
requiredThe event's identifier: the id on an event from GET /v1/remittance/events or on the body of a webhook delivery. It starts with evt_, and a redelivery carries the same one.
Returns
The event.
id
string
requiredThe event's identifier, starting with evt_, the same on a webhook delivery and on the module's events list, such as GET /v1/payroll/events. It never changes: a redelivery carries the same id, so you can recognise an event you have already handled.
type
string
requiredWhat happened, as module.resource.past_tense_verb, for example run.payslip.calculated. Pick your handler on it; data takes the shape this type promises.
schema_version
integer · minimum 1
requiredThe version of the shape data takes for this type, starting at 1. A change to the shape raises it, so check it before you read data.
org_id
string
requiredThe organisation the event belongs to, by its id, which starts with org_: the one POST /v1/registrations gave you and GET /v1/me returns. You only ever receive events for your own organisation.
sequence
integer · minimum 0
requiredPer organisation and per stream. It is how a consumer tells a replay from a new event, and it is what the delivery guarantee rests on.
occurred_at
string · date-time
requiredWhen the event happened, as an RFC 3339 timestamp in UTC. Not when it was delivered: a redelivery carries the original value.
request_id
string
optionalThe request that caused this event, where one did: the Droomwork-Request-Id that request returned, starting with req_. Absent for an event a schedule raised, such as an engagement lapsing on its end date.
livemode
boolean
requiredWhich realm the event happened in. False is the sandbox.
mocked
boolean
requiredWhether a mock produced this fact, rather than an engine computing it. Recorded on the event when it was appended and never worked out afterwards from the realm: the two answers agree while every module is on its mock and part on the day the first engine ships. See ADR-0011.
source
string
requiredWhich part of Droomwork is the authority for this fact: anchor (identity), proof (credentials), rail (engagements), flow (sourcing), match (allocation), run (payroll), remit (remittance), route (payouts), gateway (the API's front door), iam (accounts and API keys), ledger (the books), registry (rule packs), delivery (webhooks and messages), documents (rendered payslips and instruments) or intelligence (AI decisions). Read the fact from there when it matters; your own copy is never the authority.
anchorproofrailflowmatchrunremitroutegatewayiamledgerregistrydeliverydocumentsintelligenceobject
always "event"
requiredAlways event. Tells you which kind of record you are looking at, so one handler can read any response.
stream
string
requiredThe id of the record the event is about: an instruction set (remit_authority_rail_instruction_…), obligation, leg, receipt or return (remit_authority_rail_return_…). sequence counts within it; replay with both at GET /v1/remittance/events.
data
object
requiredThe record the event is about, as it stood when the event happened. Its shape follows type: an instruction set, an obligation, a leg, a receipt or an employer return.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceEventsRetrieve({ eventId: '{event_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_events_retrieve(event_id='{event_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceEventsRetrieve(event_id: '{event_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceEventsRetrieve("{event_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceEventsRetrieve(eventId: "{event_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceEventsRetrieve(ctx, "{event_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/events/%7Bevent_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "evt_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"type": "run.payslip.calculated",
"schema_version": 1,
"org_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"sequence": 0,
"occurred_at": "2026-09-01T09:00:00Z",
"livemode": true,
"mocked": true,
"source": "anchor",
"request_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "event",
"stream": "example",
"data": {}
}
/v1/remittance/audit_entries#List audit entries
remittance.audit_entries.list
Who did what, newest first. You get one row per attempt, not per success, so refusals are here too: repeated forbidden answers on one credential is what an attack looks like.
A read that succeeded is not recorded.
Query parameters
action
string
optionalRestricts the list to attempts at one route, as action reads on an entry: the method and route pattern, such as POST /v1/remittance/returns. Leave it out to get attempts at every route.
actor_id
string
optionalRestricts the list to one credential, by the exact actor_id on its entries: the id of the API key (key_…) or staff account that made the attempt. Pair it with outcome=refused to see repeated refusals; leave it out to get every actor.
resource
string
optionalRestricts the list to attempts on one kind of record, as resource reads on an entry: the collection segment of the route, such as returns, remittances, legs or receipts. Leave it out to get every kind.
resource_id
string
optionalRestricts the list to attempts on one record, as resource_id reads on an entry: the identifier the route named, such as a return's id from POST /v1/remittance/returns (remit_authority_rail_return_…). Leave it out to get every record.
outcome
string
optionalRestricts the list to one outcome: succeeded, refused (a 4xx answer) or failed (a 5xx answer). refused is where to look for a credential being probed; leave it out to get every outcome.
succeededrefusedfailedrecorded_after
string
optionalOnly entries recorded after this moment, as an RFC 3339 timestamp in UTC such as 2026-01-01T00:00:00Z; an entry at exactly this time is left out. Leave it out to read from the oldest entry.
recorded_before
string
optionalOnly entries recorded before this moment, as an RFC 3339 timestamp in UTC such as 2027-01-01T00:00:00Z; an entry at exactly this time is left out. Pair it with recorded_after to read one window, or leave it out to read up to the newest.
limit
integer
optionalHow many records to return on one page, from 1 to 100, and 25 if you leave it out. When has_more is true, pass the last record's id as starting_after to get the next page.
starting_after
string
optionalThe id of the last record on the previous page of this same list. Leave it out to get the first page; when a page comes back with has_more true, send its last record's id here to get the page after it.
Returns
A page of audit entries.
object
always "list"
requiredAlways list. Tells you which kind of record you are looking at, so one handler can read any response.
data
array of AuditEntry
requiredThe records on this page, in the order the list promises. Empty when nothing matched.
13 fields of AuditEntry
id
string
requiredThe entry's identifier, on every entry from GET /v1/remittance/audit_entries. It starts with audit_entry_ and never changes; pass it as audit_entry_id to GET /v1/remittance/audit_entries/{audit_entry_id} to retrieve one entry.
object
always "audit_entry"
requiredAlways audit_entry. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm the action happened in. False is the sandbox.
mocked
boolean
requiredWhether the route this attempt was aimed at is mocked. It describes the route, not the answer: a refused attempt and a replayed idempotent request against a mocked route both record true. Recorded with the entry, not inferred from the realm beside it.
at
string · date-time
requiredWhen the attempt was recorded, as an RFC 3339 timestamp in UTC. The list is ordered by it, newest first.
request_id
string
requiredThe request this attempt was made in: the Droomwork-Request-Id header on its response, and the request_id on any error body. Quote it when you ask us about one.
actor_type
string
requiredWhat kind of credential made the attempt: client for an API key or OAuth client, user for a signed-in person, staff for a Droomwork staff member under a grant, service when Droomwork acted for you.
actor_id
string
requiredThe id of the credential that made the attempt, of the kind actor_type says: the API key's (key_…) for client, the staff account's for staff. Pass it as actor_id to GET /v1/remittance/audit_entries to follow one credential.
action
string
requiredWhat was attempted, as the method and the route pattern.
resource
string · nullable
optionalThe kind of record acted on, as the collection segment of the route, such as returns or legs. null when the route named none.
resource_id
string · nullable
optionalThe id of the record the route named, such as a return's from POST /v1/remittance/returns (remit_authority_rail_return_…) on /v1/remittance/returns/{return_id}. null for an attempt on a collection, such as creating or listing.
outcome
string
requiredHow the attempt ended: succeeded (a status below 400), refused (a 4xx status) or failed (a 5xx status). status carries the exact code.
succeededrefusedfailedstatus
integer
requiredThe HTTP status the caller was given, such as 201, 403 or 500. outcome follows it: below 400 is succeeded, 4xx is refused, 5xx is failed.
has_more
boolean
requiredtrue when there are more records after this page. Pass the last record's id as starting_after to get the next page.
Other responses
Errors it can return
# query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
curl -X GET "https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
const result = await api.remittanceAuditEntriesList({ action: 'POST /v1/remittance/returns', actorId: 'usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', resource: 'returns', resourceId: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', outcome: 'succeeded', recordedAfter: '2026-01-01T00:00:00Z', recordedBefore: '2027-01-01T00:00:00Z', limit: 25 });// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
const response = await fetch('https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
# query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
result = api.remittance_audit_entries_list(action='POST /v1/remittance/returns', actor_id='usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', resource='returns', resource_id='remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', outcome='succeeded', recorded_after='2026-01-01T00:00:00Z', recorded_before='2027-01-01T00:00:00Z', limit=25)import os
import requests
# query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
# query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
$result = $api->remittanceAuditEntriesList(action: 'POST /v1/remittance/returns', actor_id: 'usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', resource: 'returns', resource_id: 'remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z', outcome: 'succeeded', recorded_after: '2026-01-01T00:00:00Z', recorded_before: '2027-01-01T00:00:00Z', limit: 25);<?php
// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
var result = api.remittanceAuditEntriesList("POST /v1/remittance/returns", "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "returns", "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", "succeeded", "2026-01-01T00:00:00Z", "2027-01-01T00:00:00Z", 25, null);// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
var result = api.RemittanceAuditEntriesList(action: "POST /v1/remittance/returns", actorId: "usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", resource: "returns", resourceId: "remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z", outcome: "succeeded", recordedAfter: "2026-01-01T00:00:00Z", recordedBefore: "2027-01-01T00:00:00Z", limit: 25);// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
result, _, err := client.REMITAPI.RemittanceAuditEntriesList(ctx).Action("POST /v1/remittance/returns").ActorId("usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Resource("returns").ResourceId("remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z").Outcome("succeeded").RecordedAfter("2026-01-01T00:00:00Z").RecordedBefore("2027-01-01T00:00:00Z").Limit(25).Execute()// query parameters: action (optional), actor_id (optional), resource (optional), resource_id (optional), outcome (optional), recorded_after (optional), recorded_before (optional), limit (optional), starting_after (optional)
req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/audit_entries?action=POST%20%2Fv1%2Fremittance%2Freturns&actor_id=usr_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&resource=returns&resource_id=remit_authority_rail_return_01J8XQ4M7K2N9P3R5T7V9W1Y3Z&outcome=succeeded&recorded_after=2026-01-01T00%3A00%3A00Z&recorded_before=2027-01-01T00%3A00%3A00Z&limit=25", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"object": "list",
"data": [
{
"id": "audit_entry_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "audit_entry",
"livemode": true,
"mocked": true,
"at": "2026-09-01T09:00:00Z",
"request_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"actor_type": "example",
"actor_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"action": "example",
"outcome": "succeeded",
"status": 1,
"resource": "example",
"resource_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}
],
"has_more": true
}
/v1/remittance/audit_entries/{audit_entry_id}#Retrieve an audit entry
remittance.audit_entries.retrieve
You get one entry. An identifier belonging to another organisation comes back not found rather than refused.
Path parameters
audit_entry_id
string
requiredThe entry's identifier: the id on an entry from GET /v1/remittance/audit_entries. It starts with audit_entry_.
Returns
The audit entry.
id
string
requiredThe entry's identifier, on every entry from GET /v1/remittance/audit_entries. It starts with audit_entry_ and never changes; pass it as audit_entry_id to GET /v1/remittance/audit_entries/{audit_entry_id} to retrieve one entry.
object
always "audit_entry"
requiredAlways audit_entry. Tells you which kind of record you are looking at, so one handler can read any response.
livemode
boolean
requiredWhich realm the action happened in. False is the sandbox.
mocked
boolean
requiredWhether the route this attempt was aimed at is mocked. It describes the route, not the answer: a refused attempt and a replayed idempotent request against a mocked route both record true. Recorded with the entry, not inferred from the realm beside it.
at
string · date-time
requiredWhen the attempt was recorded, as an RFC 3339 timestamp in UTC. The list is ordered by it, newest first.
request_id
string
requiredThe request this attempt was made in: the Droomwork-Request-Id header on its response, and the request_id on any error body. Quote it when you ask us about one.
actor_type
string
requiredWhat kind of credential made the attempt: client for an API key or OAuth client, user for a signed-in person, staff for a Droomwork staff member under a grant, service when Droomwork acted for you.
actor_id
string
requiredThe id of the credential that made the attempt, of the kind actor_type says: the API key's (key_…) for client, the staff account's for staff. Pass it as actor_id to GET /v1/remittance/audit_entries to follow one credential.
action
string
requiredWhat was attempted, as the method and the route pattern.
resource
string · nullable
optionalThe kind of record acted on, as the collection segment of the route, such as returns or legs. null when the route named none.
resource_id
string · nullable
optionalThe id of the record the route named, such as a return's from POST /v1/remittance/returns (remit_authority_rail_return_…) on /v1/remittance/returns/{return_id}. null for an attempt on a collection, such as creating or listing.
outcome
string
requiredHow the attempt ended: succeeded (a status below 400), refused (a 4xx status) or failed (a 5xx status). status carries the exact code.
succeededrefusedfailedstatus
integer
requiredThe HTTP status the caller was given, such as 201, 403 or 500. outcome follows it: below 400 is succeeded, 4xx is refused, 5xx is failed.
Other responses
Errors it can return
curl -X GET "https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D" \
-H "Droomwork-Api-Key: $DROOMWORK_API_KEY"import { Configuration, REMITApi } from '@droomwork/sdk';
const api = new REMITApi(new Configuration({ basePath: 'https://sandbox.droomwork.io', accessToken: process.env.DROOMWORK_API_KEY }));
const result = await api.remittanceAuditEntriesRetrieve({ auditEntryId: '{audit_entry_id}' });const response = await fetch('https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D', {
method: 'GET',
headers: {
'Droomwork-Api-Key': process.env.DROOMWORK_API_KEY,
},
});
const result = await response.json();import os
import droomwork
config = droomwork.Configuration(access_token=os.environ['DROOMWORK_API_KEY'])
config.host = 'https://sandbox.droomwork.io'
client = droomwork.ApiClient(config)
api = droomwork.REMITApi(client)
result = api.remittance_audit_entries_retrieve(audit_entry_id='{audit_entry_id}')import os
import requests
response = requests.request(
'GET',
'https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D',
headers={
'Droomwork-Api-Key': os.environ['DROOMWORK_API_KEY'],
},
)
result = response.json()<?php
require_once __DIR__ . '/vendor/autoload.php';
$config = DroomworkSdk\Configuration::getDefaultConfiguration()
->setHost('https://sandbox.droomwork.io')
->setAccessToken(getenv('DROOMWORK_API_KEY'));
$api = new DroomworkSdk\Api\REMITApi(new GuzzleHttp\Client(), $config);
$result = $api->remittanceAuditEntriesRetrieve(audit_entry_id: '{audit_entry_id}');<?php
$ch = curl_init('https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'GET',
CURLOPT_HTTPHEADER => [
'Droomwork-Api-Key: ' . getenv('DROOMWORK_API_KEY'),
],
]);
$result = json_decode(curl_exec($ch), true);import com.droomwork.sdk.ApiClient;
import com.droomwork.sdk.Configuration;
import com.droomwork.sdk.api.RemitApi;
ApiClient client = Configuration.getDefaultApiClient();
client.setBasePath("https://sandbox.droomwork.io");
client.setAccessToken(System.getenv("DROOMWORK_API_KEY"));
RemitApi api = new RemitApi(client);
var result = api.remittanceAuditEntriesRetrieve("{audit_entry_id}");var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D"))
.header("Droomwork-Api-Key", System.getenv("DROOMWORK_API_KEY"))
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using Droomwork.Sdk.Api;
using Droomwork.Sdk.Client;
var config = new Configuration { BasePath = "https://sandbox.droomwork.io" };
config.AccessToken = Environment.GetEnvironmentVariable("DROOMWORK_API_KEY");
var api = new REMITApi(config);
var result = api.RemittanceAuditEntriesRetrieve(auditEntryId: "{audit_entry_id}");using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Get, "https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D");
request.Headers.Add("Droomwork-Api-Key", Environment.GetEnvironmentVariable("DROOMWORK_API_KEY"));
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();import droomwork "github.com/fenibofubara/droomwork-sdk-go"
ctx := context.WithValue(context.Background(), droomwork.ContextAPIKeys, map[string]droomwork.APIKey{
"apiKey": {Key: os.Getenv("DROOMWORK_API_KEY")},
})
cfg := droomwork.NewConfiguration()
cfg.Servers = droomwork.ServerConfigurations{{URL: "https://sandbox.droomwork.io"}}
client := droomwork.NewAPIClient(cfg)
result, _, err := client.REMITAPI.RemittanceAuditEntriesRetrieve(ctx, "{audit_entry_id}").Execute()req, _ := http.NewRequest("GET", "https://sandbox.droomwork.io/v1/remittance/audit_entries/%7Baudit_entry_id%7D", nil)
req.Header.Set("Droomwork-Api-Key", os.Getenv("DROOMWORK_API_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
result, _ := io.ReadAll(res.Body)
{
"id": "audit_entry_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"object": "audit_entry",
"livemode": true,
"mocked": true,
"at": "2026-09-01T09:00:00Z",
"request_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"actor_type": "example",
"actor_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z",
"action": "example",
"outcome": "succeeded",
"status": 1,
"resource": "example",
"resource_id": "sub_01J8XQ4M7K2N9P3R5T7V9W1Y3Z"
}