Skip to main content

Status flow

draft
  └─► invite_pending   (counterparty invited)
        └─► funded      (payment confirmed)
              ├─► active        (counterparty accepted)
              │     ├─► inspection   (goods-based: 24h window)
              │     │     └─► released ✓
              │     ├─► released ✓    (immediate release categories)
              │     └─► disputed ─► resolved → released / refunded
              ├─► cancelled ✗   (before acceptance)
              └─► refunded ✗

Step-by-step API calls

1. Create the escrow

POST /escrow-create
Authorization: Bearer <token>

{
  "category": "goods_products",
  "payer_role": "initiator",
  "title": "iPhone 15 Pro Max 256GB",
  "counterparty_phone": "+2348012345679",
  "amount": 500000
}
Response includes fee_breakdown (so your UI can show costs before payment) and conversation_id.

2. Fund the escrow

POST /escrow-fund
Authorization: Bearer <token>

{
  "escrow_id": "<id>",
  "funding_source": "wallet"
}
Alternatively fund via card_id. Status moves to funded → notification sent to counterparty.

3. Counterparty accepts

POST /escrow-accept
Authorization: Bearer <token>

{
  "escrow_id": "<id>"
}
Status moves to active. For goods_products, a 24-hour inspection window starts automatically.

4. Release funds

POST /escrow-release
Authorization: Bearer <token>

{
  "escrow_id": "<id>"
}
Funds are transferred to the payee’s wallet. If auto_withdraw is on, a bank transfer fires immediately.

Key rules

Buyer and seller cannot be the same user. The API enforces this at creation.
Once funded, an escrow can only be cancelled via POST /escrow-cancel, which internally raises a dispute. The counterparty must agree or an admin resolves it.
  • Only the payer can call POST /escrow-fund
  • Only the counterparty can call POST /escrow-accept or POST /escrow-decline
  • Either party can call POST /dispute-raise on an active/inspection escrow
  • Only the payer (or admin) can call POST /escrow-release