Export as

API Reference

Complete REST API reference for OFFER-HUB — endpoints, parameters, and response schemas.

The OFFER-HUB Orchestrator exposes a RESTful JSON API. All endpoints are prefixed with /api/v1.

Base URL

typescript
https://{your-orchestrator-domain}/api/v1

For local development:

typescript
http://localhost:4000/api/v1

Authentication

All requests require authentication via a Bearer token (API Key).

Request Header

http
Authorization: Bearer ohk_live_xxxxxxxxxxxxxxxxxxxxxxxx

Getting an API Key

Create an API key using your master key:

bash
curl -X POST http://localhost:4000/api/v1/auth/api-keys \
  -H "Authorization: Bearer YOUR_OFFERHUB_MASTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Marketplace", "scopes": ["read", "write"]}'

Response:

json
{
  "data": {
    "id": "key_abc123",
    "key": "ohk_live_xxxxxxxxxxxx",
    "name": "My Marketplace",
    "scopes": ["read", "write"]
  }
}
Danger

Save the key value immediately - it's only shown once!

API Key Scopes

ScopePermissions
readAll GET endpoints
writePOST to create/modify resources
supportResolve disputes, add comments

Common Headers

Request Headers

HeaderRequiredDescription
AuthorizationYesBearer {api_key}
Content-TypeYes (POST/PUT)application/json
Idempotency-KeyConditionalUUID for state-changing POSTs
X-Request-IDNoUUID for correlation/debugging

Response Headers

HeaderDescription
X-Request-IDEcho of request ID or auto-generated
X-Idempotency-KeyEcho of key if applied
X-RateLimit-LimitRequest limit
X-RateLimit-RemainingRemaining requests
X-RateLimit-ResetReset timestamp

Response Format

Success Response

json
{
  "id": "ord_abc123",
  "status": "ORDER_CREATED",
  "amount": "100.00",
  "currency": "USD",
  "created_at": "2026-01-12T10:00:00.000Z",
  "updated_at": "2026-01-12T10:00:00.000Z"
}

List Response

json
{
  "data": ["..."],
  "pagination": {
    "has_more": true,
    "next_cursor": "ord_abc123"
  }
}

Error Response

json
{
  "error": {
    "code": "INSUFFICIENT_FUNDS",
    "message": "Available balance is less than requested amount",
    "details": {
      "available": "50.00",
      "requested": "100.00"
    }
  }
}

Error Codes

CodeHTTPWhen to Use
VALIDATION_ERROR400Invalid fields in request
UNAUTHORIZED401Missing or invalid API key
INSUFFICIENT_SCOPE403API key lacks required scope
USER_NOT_FOUND404User does not exist
ORDER_NOT_FOUND404Order does not exist
INVALID_STATE409Invalid state transition
IDEMPOTENCY_KEY_REUSED409Same key with different body
INSUFFICIENT_FUNDS422Balance too low
RATE_LIMITED429Too many requests
PROVIDER_TIMEOUT504External provider timeout

Escrows

Escrow contracts hold funds securely between buyers and sellers until project completion.

Initialize an Escrow

POST /api/v1/orders/{id}/escrow

Creates a new escrow contract between buyer and seller. Funds are held until release.

Request Body

ParameterTypeRequiredDescription
amountstringYesAmount to escrow
currencystringYesCurrency code (USD, XLM, USDC)
json
{
  "amount": "2500.00",
  "currency": "USD"
}

Response

json
{
  "data": {
    "escrow_id": "esc_01JKL",
    "order_id": "ord_abc123",
    "buyer_id": "usr_01ABC",
    "seller_id": "usr_02ABC",
    "amount": "2500.00",
    "currency": "USD",
    "status": "PENDING",
    "created_at": "2026-02-01T14:00:00.000Z"
  }
}

Fund Escrow

POST /api/v1/orders/{id}/escrow/fund

Funds an existing escrow contract.

Warning

Returns 422 INSUFFICIENT_FUNDS if the buyer has insufficient balance.

Release Escrow

POST /api/v1/orders/{id}/resolution/release

Releases held funds from an escrow to the seller upon project completion.

Response

json
{
  "data": {
    "escrow_id": "esc_01JKL",
    "status": "RELEASED",
    "released_amount": "2500.00",
    "released_at": "2026-02-10T16:00:00.000Z"
  }
}

Refund Escrow

POST /api/v1/orders/{id}/resolution/refund

Refunds escrowed funds back to the buyer.

Open Dispute

POST /api/v1/orders/{id}/resolution/dispute

Opens a dispute on an escrow for resolution.


Transactions

Retrieve user transaction and balance history.

Get User Balance

GET /api/v1/users/{id}/balance

Returns the user's current balance across all currencies.

$
curl -X GET http://localhost:4000/api/v1/users/usr_abc/balance -H "Authorization: Bearer TOKEN"

Response

json
{
  "data": {
    "user_id": "usr_abc123",
    "balances": [
      { "currency": "USD", "available": "1250.00", "held": "200.00" },
      { "currency": "XLM", "available": "5000.00", "held": "0.00" }
    ]
  }
}
FieldTypeDescription
currencystringCurrency code
availablestringSpendable balance
heldstringBalance locked in escrows

Get Deposit Address

GET /api/v1/users/{id}/wallet/deposit

Returns a deposit address for the user to fund their account.


Webhooks

Receive real-time event notifications from OFFER-HUB via HTTP webhooks.

See the Webhooks documentation for complete details on:

  • Payload structures
  • Signature verification
  • Retry logic

Available Events

EventTrigger
escrow.createdNew escrow contract created
escrow.fundedEscrow has received funds
escrow.releasedSeller paid; escrow completed
escrow.disputedDispute opened on an escrow
escrow.refundedEscrow refunded to buyer

Assets

Create Withdrawal

POST /api/v1/withdrawals

Initiate a withdrawal from user balance.

Request Body

ParameterTypeRequiredDescription
user_idstringYesUser requesting withdrawal
amountstringYesAmount to withdraw
currencystringYesCurrency code
destinationobjectYesWithdrawal destination
json
{
  "user_id": "usr_abc123",
  "amount": "100.00",
  "currency": "USD",
  "destination": {
    "type": "stellar",
    "address": "GBCG42WTVWPO4Q6N..."
  }
}

Get Withdrawal

GET /api/v1/withdrawals/{id}

Returns withdrawal status and details.


Pagination

List endpoints support cursor-based pagination:

Request

typescript
GET /orders?limit=20&cursor=ord_xyz789
ParamDefaultMaxDescription
limit20100Items per page
cursor--ID of last item from previous page

Response

json
{
  "data": ["..."],
  "pagination": {
    "has_more": true,
    "next_cursor": "ord_abc123"
  }
}

Filters

List endpoints accept query parameter filters:

typescript
GET /orders?status=IN_PROGRESS&buyer_id=usr_abc&created_after=2026-01-01
FilterTypeExample
statusstringIN_PROGRESS
buyer_idstringusr_abc123
seller_idstringusr_xyz789
created_afterISO date2026-01-01T00:00:00Z
created_beforeISO date2026-01-31T23:59:59Z

Idempotency

All state-changing POSTs accept Idempotency-Key to prevent duplicate operations:

http
POST /orders
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{ "order_data": "..." }

Behavior

  1. First request: Processed normally
  2. Repeated request (same key): Returns original response
  3. Different body + same key: Returns 409 IDEMPOTENCY_KEY_REUSED

Idempotency Windows

ResourceWindow
Top-ups24 hours
Withdrawals24 hours
Orders7 days
Escrow ops7 days
DisputesForever

Rate Limiting

EndpointLimit
General100 req/min per API key
POST /topups10 req/min per user
POST /withdrawals5 req/min per user
GET /events1 SSE connection per user

Response When Exceeded

http
HTTP/1.1 429 Too Many Requests
Retry-After: 60

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Too many requests",
    "details": {
      "retry_after": 60
    }
  }
}

Available Endpoints

Auth & Config

EndpointMethodDescription
/auth/api-keysPOSTCreate API key
/auth/api-keysGETList API keys
/healthGETHealth check

Users

EndpointMethodDescription
/usersPOSTCreate user
/usersGETList users
/users/{id}GETGet user
/users/{id}/balanceGETGet balance
/users/{id}/wallet/depositGETGet deposit address

Orders

EndpointMethodDescription
/ordersPOSTCreate order
/ordersGETList orders
/orders/{id}GETGet order
/orders/{id}/reservePOSTReserve funds
/orders/{id}/cancelPOSTCancel order

Escrow

EndpointMethodDescription
/orders/{id}/escrowPOSTCreate escrow
/orders/{id}/escrow/fundPOSTFund escrow

Resolution

EndpointMethodDescription
/orders/{id}/resolution/releasePOSTRelease to seller
/orders/{id}/resolution/refundPOSTRefund to buyer
/orders/{id}/resolution/disputePOSTOpen dispute
/disputes/{id}/resolvePOSTResolve dispute

Withdrawals

EndpointMethodDescription
/withdrawalsPOSTCreate withdrawal
/withdrawals/{id}GETGet withdrawal
/withdrawals/{id}/commitPOSTCommit withdrawal (AirTM)

Events

EndpointMethodDescription
/eventsGETSSE event stream

Versioning

The API uses path versioning:

typescript
/api/v1/orders
/api/v2/orders  (future)
  • v1 is the current stable version
  • Deprecated versions will have 6 months notice

Next Steps