Partner API
Embed escrow-protected payments into your platform. Collect funds, hold in escrow, release on confirmation — fully automated, fully auditable.
https://api.posteering.com/api/v1 | All requests require X-API-Key header. Contact admin@posteering.com to obtain your API key.Overview
The Posteering Partner API gives external platforms access to our escrow infrastructure. Use it to protect marketplace transactions, service payments, property deposits, remittance payouts, and any conditional payment flow.
Authentication
All requests must include your API key in the request header.
X-API-Key: your_api_key_here
Error Handling
All errors return a consistent JSON structure:
{"statusCode": 400, "error": "invalid_escrow_status", "message": "Escrow cannot be released. Current status: initiated. Must be funded."}
| Status Code | Meaning |
|---|---|
| 400 | Bad request — invalid parameters or status transition |
| 401 | Unauthorized — missing or invalid API key |
| 404 | Escrow not found or does not belong to your account |
| 422 | Validation error — check request body fields |
| 500 | Server error — contact support |
Create Escrow
Creates a new escrow record. Returns a unique ref for all subsequent operations.
Request Body
| Field | Type | Description |
|---|---|---|
| type* | string | goods, services, property, conditional |
| amount* | integer | Amount in kobo. Minimum 10000 (NGN 100) |
| currency* | string | ISO 4217. Example: NGN |
| payerEmail* | string | Buyer / payer email |
| recipientEmail* | string | Seller / recipient email |
| description* | string | What is being escrowed. Max 255 chars |
| ttlHoursoptional | integer | Hours until auto-expiry. Default: 24 |
| webhookUrloptional | string | URL for state change events |
| metadataoptional | object | Custom key-value data returned on all events |
Example Request
POST /api/v1/escrow/partner/create
X-API-Key: your_api_key_here
Content-Type: application/json
{
"type": "goods",
"amount": 500000,
"currency": "NGN",
"payerEmail": "buyer@example.com",
"recipientEmail": "seller@example.com",
"description": "MacBook Pro 2023 16 inch",
"ttlHours": 72,
"webhookUrl": "https://yourplatform.com/webhooks/escrow",
"metadata": { "orderId": "ORD-001" }
}
Response
{
"success": true,
"ref": "EPT-1743512345-A1B2C3D4",
"status": "initiated",
"amount": 500000,
"currency": "NGN",
"expiresAt": "2026-04-04T12:00:00.000Z",
"message": "Escrow initiated. Share the ref with your payer to complete funding."
}
Get Escrow Status
Returns current state of an escrow. Only returns escrows belonging to your API key.
Response
{
"success": true,
"escrow": {
"ref": "EPT-1743512345-A1B2C3D4",
"type": "goods",
"status": "funded",
"amount": 500000,
"currency": "NGN",
"description": "MacBook Pro 2023 16 inch",
"payerEmail": "buyer@example.com",
"recipientEmail": "seller@example.com",
"metadata": { "orderId": "ORD-001" },
"createdAt": "2026-04-01T12:00:00.000Z",
"expiresAt": "2026-04-04T12:00:00.000Z",
"releasedAt": null,
"cancelledAt": null
}
}
Release Escrow
Releases escrowed funds to the recipient. Escrow must be in funded status.
Request Body
| Field | Type | Description |
|---|---|---|
| reasonoptional | string | Reason for release. Max 500 chars |
Response
{"success": true, "ref": "EPT-1743512345-A1B2C3D4", "status": "released", "message": "Escrow released. Funds will be disbursed to recipient."}
Cancel Escrow
Cancels escrow and initiates refund to payer. Cannot cancel once released, cancelled, or expired.
Request Body
| Field | Type | Description |
|---|---|---|
| reason* | string | Reason for cancellation. Max 500 chars |
Response
{"success": true, "ref": "EPT-1743512345-A1B2C3D4", "status": "cancelled", "message": "Escrow cancelled. Refund initiated to payer."}
Register Webhook
Register a URL to receive escrow state change events signed with HMAC SHA256.
Request Body
| Field | Type | Description |
|---|---|---|
| webhookUrl* | string | HTTPS URL to receive events |
| webhookSecretoptional | string | Secret used to sign payloads. Strongly recommended. |
Webhook Events
Every state change fires a POST to your registered webhook URL:
{
"event": "escrow.released",
"timestamp": "2026-04-01T14:30:00.000Z",
"data": {
"ref": "EPT-1743512345-A1B2C3D4",
"status": "released",
"amount": 500000,
"currency": "NGN",
"releasedAt": "2026-04-01T14:30:00.000Z"
}
}
- escrow.initiatedinfoEscrow created — awaiting payer funding
- escrow.fundedactionPayer funded — ready to release
- escrow.releasedfinalFunds released to recipient
- escrow.cancelledfinalCancelled — refund initiated
- escrow.expiredfinalTTL elapsed — auto-cancelled
Signature Verification
When a webhookSecret is registered, every request includes X-BankRail-Signature. Verify on your server:
const crypto = require('crypto');
function verifyWebhook(rawBody, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
app.post('/webhooks/escrow', express.raw({ type: 'application/json' }), (req, res) => {
const sig = req.headers['x-bankrail-signature'];
if (!verifyWebhook(req.body, sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// handle event.event
res.sendStatus(200);
});
Escrow Types
| Type | Use Case |
|---|---|
| goods | Marketplace — buyer pays, seller ships, buyer confirms receipt |
| services | Freelance — client pays, work delivered, client confirms |
| property | Property deposit — held until documents signed |
| conditional | Custom trigger — partner controls release condition |
Escrow Statuses
| Status | Meaning |
|---|---|
| initiated | Created. Awaiting payer to fund. |
| funded | Payer completed payment. Funds held securely. |
| released | Funds released. Disbursement to recipient in progress. |
| cancelled | Cancelled. Refund initiated to payer. |
| expired | TTL elapsed without funding. Auto-cancelled. |
Remittance Payout Flow
For remittance partners sending cross-border payouts to Nigerian beneficiaries via the Posteering operator network: