Custody vendor portal

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

EndpointScopeWhat it does
POST /v1/ordersorders:writeCreate an order for fulfillment (customer + lines)
GET /v1/orders/:idreadStatus, lines, carrier tracking
POST /v1/orders/:id/cancelorders:writeCancel before picking starts
GET /v1/inventoryreadYour on-hand stock by SKU / status / grade
POST /v1/inboundorders:writeAnnounce an inbound shipment (ASN)
GET /v1/units/:serialreadUnit status + the full hash-chained custody history
GET /v1/invoicesreadYour 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", …}.