Prepare your first payroll draft

Prepare an isolated Test draft, verify it and stop before approval or payment.

Before you start

You are the company’s integration developer. Call https://api.kuahr.com with a Test key with payroll:write and payroll:read. If you create an employee first, also grant employees:write and follow employee creation.

An authorised company administrator must prepare an eligible payroll roster in the same company and Test partition: employment type, active employment, an effective salary structure, supported country calculator and required statutory profile information. Ask them to provision salary setup for the intended Test employee or provide a prepared Test fixture. The public API has no salary-setting endpoint; an employee-creation response alone cannot make a payroll-ready roster.

Create the draft

Choose the intended month and year for the prepared roster. Store a unique PAYROLL_OPERATION_KEY and the exact request body before sending it; reuse both on a retry. This example uses November 2026, so adjust the period deliberately if your fixture uses another month.

curl --fail-with-body https://api.kuahr.com/v1/payroll/runs \
  -X POST -H "X-Api-Key: $KUA_API_KEY" \
  -H "Idempotency-Key: $PAYROLL_OPERATION_KEY" \
  -H "Content-Type: application/json" \
  -d '{"year":2026,"month":11}'
import { Kua } from "@kuahr/node";
const kua = new Kua({
  apiKey: process.env.KUA_API_KEY!,
});
const run = await kua.payrollRuns.create(
  { year: 2026, month: 11 },
  { idempotencyKey: process.env.PAYROLL_OPERATION_KEY! },
);
console.log(run.id, run.status);
import os
from kua import Kua
with Kua(api_key=os.environ["KUA_API_KEY"]) as kua:
    run = kua.payroll_runs.create(
        year=2026, month=11,
        idempotency_key=os.environ["PAYROLL_OPERATION_KEY"],
    )
    print(run.id, run.status)

HTTP 201 returns the run ID, period and status: "Draft". Keep the ID in your integration record. Creating a draft moves no money.

Verify it in the Test run list

curl --fail-with-body https://api.kuahr.com/v1/payroll/runs \
  -H "X-Api-Key: $KUA_API_KEY"

Find the returned run ID in the array and check its period and Draft status. The list contains only your company’s Test runs. The Node equivalent is kua.payrollRuns.list(); Python is kua.payroll_runs.list().

Resolve an unsuccessful draft

ResultWhat to check
PAYROLL_RUN_EMPTYNo eligible salaried Test roster for this period. Ask the administrator to check active employment, mode and effective salary setup.
Country/statutory validation errorResolve the returned profile or calculator prerequisite with the administrator. Do not assume an NGN example applies to every country.
Scope or workspace denialCheck the key’s grants and approval for that company.
Timeout or lost 201Reuse the same credential, operation key and exact body; then list runs before starting another operation.
Idempotency conflictFollow the specific conflict code in retry guidance.

Stop at the right outcome

Done when: the run ID appears as a Test Draft in the list. Approval, funding, disbursement, employee-wallet credit and bank withdrawal are separate outcomes, performed through authorised product flows. The public payroll API here does not expose an approve or pay operation.

Events and webhooks are Live-key only, so this Test draft journey does not promise an event. For a separately authorised receiver integration, follow webhook setup. Before any live integration, review go-live readiness.

Search documentation

↑ ↓ to move · Enter to open · Esc to close