Quickstart
Integrate the One API end to end — onboard, authenticate, and make your first product call with real, copy-paste requests.
This is the fastest path from nothing to a live product call. Every request below is real and callable against the sandbox. You onboard once through the One API and reach every product you enable from a single signed surface.
Base URL: https://one.posteering.com/api/v1/one. All examples target the sandbox.
Register and get your credentials
POST /partners creates your partner identity and issues two credentials at
sign-up — a JWT on-ramp and a durable HMAC root — both resolving the same partner.
Each signing secret is returned once; store both securely.
curl -X POST https://one.posteering.com/api/v1/one/partners \\
-H "Content-Type: application/json" \\
-d '{
"organization_name": "Posteering Treasury",
"email": "dev@posteeringtreasury.com"
}'{
"partner": {
"id": "ptr_9c70...",
"organization_name": "Posteering Treasury",
"email": "dev@posteeringtreasury.com",
"created_at": "2026-06-13T18:00:00Z"
},
"credential": { "id": "crd_2f1a...", "grade": "jwt", "secret": "eyJhbGci..." },
"hmac_credential": {
"id": "crd_8d3b...",
"grade": "hmac",
"key_id": "oak_3f9c1a7e5b2d4860c8e1f0a2",
"secret": "9f8e7d6c5b4a39281706f5e4d3c2b1a0f9e8d7c6b5a49382"
}
}Both secrets are shown once
The JWT secret (your bearer token) and the HMAC key_id + secret appear in this
response only and are never retrievable again. The HMAC root does not expire and is your
recoverable credential — an expired JWT is always re-mintable via the root with
POST /credentials.
Select products and provision
POST /onboard does everything register does and records your product selection,
self-provisioning the products that allow it — in one call.
curl -X POST https://one.posteering.com/api/v1/one/onboard \\
-H "Content-Type: application/json" \\
-d '{
"organization_name": "Posteering Treasury",
"email": "dev@posteeringtreasury.com",
"entitlements": ["ledger", "bankrail-gateway"],
"context_reference": "posteering-treasury-prod"
}'The result names what was provisioned now versus what awaits approval. It carries no
secret — you obtain or re-mint credentials through POST /partners and
POST /credentials.
{
"partner_id": "ptr_9c70...",
"context_id": "ctx_5a21...",
"entitlements": ["ledger", "bankrail-gateway"],
"provisioned": [{ "product": "ledger" }],
"pending": ["bankrail-gateway"],
"warnings": []
}Self-serve vs approval-required
Self-serve products (e.g. ledger) are provisioned immediately and appear in
provisioned. Payment rails (e.g. bankrail-gateway) are recorded in pending and
become reachable only after an operator approves them. When entitlements include
bankrail-gateway, a bankrail classification is required.
Make your first product call
With a credential in hand, you reach a product through passthrough. You sign only your One-API leg; the gateway threads the product's own credential for you.
curl -X POST \\
https://one.posteering.com/api/v1/one/products/ledger/passthrough/accounts \\
-H "Content-Type: application/json" \\
-H "One-Api-Hmac-Key-Id: key_live_..." \\
-H "One-Api-Hmac-Timestamp: 2026-06-28T10:00:00Z" \\
-H "One-Api-Hmac-Nonce: 9f2c..." \\
-H "One-Api-Hmac-Signed-Headers: one-context" \\
-H "One-Api-Hmac-Signature: <hex-hmac-sha256>" \\
-H "One-Context: posteering-treasury-prod" \\
-d '{ "class": "asset", "currencies": ["NGN"] }'The path after passthrough/ is the product's own route, carried verbatim — here,
Ledger's /accounts. The product's response returns unchanged, with its own status
code and body.
Don't hand-build the signature
Copy a ready-made signer — curl, JavaScript, Python, Go, or Postman — from Authentication. Each is self-contained and verified against the gateway's own verifier, so a signature it produces is accepted by construction.
In Node
Grab the self-contained signOneApiRequest from
Authentication (the JavaScript tab), then
call it and send the exact bytes you signed:
// signOneApiRequest — copy it from Authentication (the JavaScript tab).
const body = JSON.stringify({ class: 'asset', currencies: ['NGN'] });
const bodyBytes = Buffer.from(body, 'utf8');
// Sign the consumer leg. Bind the value of any header you want covered
// (here, One-Context) by listing it in signHeaders and supplying its value
// in headerValues.
const { headers } = signOneApiRequest({
method: 'POST',
path: '/api/v1/one/products/ledger/passthrough/accounts',
keyId: process.env.ONE_API_KEY_ID,
secret: process.env.ONE_API_SECRET,
bodyBytes,
signHeaders: ['one-api-hmac-timestamp', 'one-api-hmac-nonce', 'one-context'],
headerValues: { 'one-context': 'posteering-treasury-prod' },
});
const res = await fetch(
'https://one.posteering.com/api/v1/one/products/ledger/passthrough/accounts',
{
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json',
'One-Context': 'posteering-treasury-prod',
},
body,
},
);
const account = await res.json();Body is signed as raw bytes
Sign the exact bytes you send. Pass the request body to the signer as bodyBytes (a
Buffer) and send those same bytes — don't re-serialize between signing and sending, or
the hashes won't match.
What you can call
Once entitled, every product route is reachable through the same passthrough pattern:
/products/ledger/passthrough/{path}— accounts, transactions, holds, export/products/bankrail-gateway/passthrough/{path}— virtual accounts, payouts, callbacks
You can also use the One API's own money operations directly — /collections/pool,
/payouts — and manage sub-accounts at /partners/me/subaccounts.
Next
- Authentication — the signing details in full.
- Passthrough — how byte-faithful forwarding works.
- API reference — every endpoint, with a live playground.