Management API
Server-side endpoints for onboarding: merchants, authority credentials, registers. All require a management API key and run from your backend — never from a client app.
Two different keys
Management endpoints authenticate with
Authorization: Bearer kb_live_... (your project's management key). The SDK endpoints your app calls use x-api-key: pk_.... Never ship a management key in an app binary.Merchants
POST
/v1/projects/{project_id}/fiscal/merchantsCreate a taxpayer. Returns the merchant id used by every other fiscal endpoint.
curl -X POST https://api.koolbase.com/v1/projects/$PROJECT_ID/fiscal/merchants \
-H "Authorization: Bearer $KB_KEY" -H "Content-Type: application/json" \
-d '{ "legal_name": "Tilla Retail Ltd", "tax_id": "C0012345678" }'GET
/v1/projects/{project_id}/fiscal/merchantsList the project's merchants.
Credentials
POST
/v1/projects/{project_id}/fiscal/merchants/{merchant_id}/credentialsStore an authority credential. The secret is encrypted at rest and never returned by any endpoint — the response is metadata only.
curl -X POST .../fiscal/merchants/$MERCHANT_ID/credentials \
-H "Authorization: Bearer $KB_KEY" -H "Content-Type: application/json" \
-d '{
"name": "GRA production key",
"credential_type": "gh-gra-v1",
"payload": { "security_key": "..." }
}'
# -> { "id": "...", "status": "active", "active_version": 1, ... }GET
/v1/projects/{project_id}/fiscal/merchants/{merchant_id}/credentialsList credentials (metadata only).
POST
/v1/projects/{project_id}/fiscal/credentials/{credential_id}/rotateStore a new version of the same credential. Previous versions are retained as evidence of what authenticated past submissions; they are never overwritten.
POST
/v1/projects/{project_id}/fiscal/credentials/{credential_id}/revokeImmediately kill a credential. New transactions on devices using it are blocked before consuming a fiscal number; already-sealed transactions move to
attention without attempting delivery. Revocation is terminal — recovery means storing a new credential and attaching it.Devices (registers)
POST
/v1/projects/{project_id}/fiscal/merchants/{merchant_id}/devicesActivate a register. Creates its counter chains at the values you specify and binds its credential and authority identity.
curl -X POST .../fiscal/merchants/$MERCHANT_ID/devices \
-H "Authorization: Bearer $KB_KEY" -H "Content-Type: application/json" \
-d '{
"jurisdiction": "GH",
"adapter_id": "gh-gra",
"initial_counters": { "INV": 4391 },
"credential_id": "...",
"authority_registration_id": "C0012345678-001"
}'
# -> { "device_id": "..." }Counters start where the merchant is
initial_counters must cover exactly the counters the jurisdiction declares, and should be the merchant's current series position. A business already at invoice 4,391 continues from there — Koolbase never restarts an existing series or invents a starting point.GET
/v1/projects/{project_id}/fiscal/devices/{device_id}Read a register's state: status, counters, active credential.
POST
/v1/projects/{project_id}/fiscal/devices/{device_id}/credentialPoint a register at a different credential — the recovery path after revocation.
POST
/v1/projects/{project_id}/fiscal/devices/{device_id}/suspendStop a register accepting new transactions. Work already sealed continues to the authority.
POST
/v1/projects/{project_id}/fiscal/devices/{device_id}/resumeReturn a suspended register to service.
SDK endpoints
These are what the client SDK calls. Documented here for platforms without a Koolbase SDK yet.
POST
/v1/sdk/fiscal/submitBody:
{ device_id, client_ref, payload }. Idempotent on client_ref. Returns the intent state.GET
/v1/sdk/fiscal/status?device_id=&client_ref=Returns the same intent shape, including the certification once fiscalized.
{
"intent_id": "037649f2-...",
"status": "fiscalized",
"numbers": { "INV": 4391 },
"sealed_at": "2026-08-18T19:16:29Z",
"certification": {
"num": "C0012345678-001-00004391",
"ysdcregsig": "ULOE-AVYC-F3KO-457H",
"ysdcrecnum": "1001-6317-NS1345",
"qr_code": "https://verification.vat-gh.com?data=..."
}
}