Custody API
Integrate your store, warehouse team, or ERP with your Custody tenant. Keys and webhook endpoints are managed from your dashboard — both are shown once at creation, so store them securely.
Base URL: https://api.wms.cisomarketplace.services · Auth:
Authorization: Bearer ck_… · 120 req/min per key · idempotent POSTs via an
Idempotency-Key header.
Endpoints
| Endpoint | Scope | What it does |
|---|---|---|
POST /v1/orders | orders:write | Create an order for fulfillment (customer + lines) |
GET /v1/orders/:id | read | Status, lines, carrier tracking |
POST /v1/orders/:id/cancel | orders:write | Cancel before picking starts |
GET /v1/inventory | read | Your on-hand stock by SKU / status / grade |
POST /v1/inbound | orders:write | Announce an inbound shipment (ASN) |
GET /v1/units/:serial | read | Unit status + the full hash-chained custody history |
GET /v1/invoices | read | Your invoices |
Create an order
curl -s https://api.wms.cisomarketplace.services/v1/orders \
-H "Authorization: Bearer $CUSTODY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"external_ref": "SHOP-1042",
"customer": {"name":"Jane Doe","email":"jane@example.com",
"street1":"1 Main St","city":"Austin","state":"TX",
"zip":"78701","country":"US"},
"lines": [{"product_id":"PRD_…","qty":1}]
}' Webhooks — we call you
Register an HTTPS endpoint from your dashboard and we push events as they happen:
order.shipped, order.delivered, order.exception,
inbound.received, inbound.discrepancy, rma.received,
rma.triaged, unit.quarantined.
Every delivery is signed:
X-Custody-Signature: hmac-sha256-hex=<HMAC-SHA256 of the raw body>,
keyed by your endpoint's secret. Verify it before trusting the payload.
Respond 2xx within 10 seconds; failures retry up to 5 times. Delivery history is
visible on your dashboard.
// Node.js verification
import { createHmac, timingSafeEqual } from 'node:crypto';
const expected = 'hmac-sha256-hex=' +
createHmac('sha256', SECRET).update(rawBody).digest('hex');
const ok = timingSafeEqual(Buffer.from(expected),
Buffer.from(req.headers['x-custody-signature'])); Errors
401 bad/missing key · 403 insufficient_scope ·
404 not_found · 409 state conflicts (e.g.
insufficient_stock, not_cancelable) · 429 rate
limited. Bodies are always {"error": "code", …}.