Integrations / Custom

Generic integration guide

If you’re not on WooCommerce or Shopify, this is the playbook. Works with Node, Python, Go, Java, .NET, Ruby, PHP, and anything else that can speak HTTPS.

Step 1 — Authenticate

Every request carries a single header: Authorization: Bearer sk_live_xxxx. Create keys in your dashboard. Use sk_test_ keys in development.

Step 2 — Quote a rate

bash
curl https://api.serianshipkit.com/api/v1/rates \
  -H "Authorization: Bearer $SERIAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "shipper":   { "name":"Acme","street1":"12 Main","city":"Accra","state":"Greater Accra","zip":"00233","country":"GH" },
    "recipient": { "name":"Jane", "street1":"10 Oak","city":"Lagos","state":"Lagos","zip":"100001","country":"NG" },
    "parcels":   [{ "length":20,"width":15,"height":10,"weight":1,"dimension_unit":"CM","weight_unit":"KG" }]
  }'

You get back an array of rates, each with a rate_id you can hand straight to the next endpoint.

Step 3 — Print the label

bash
curl https://api.serianshipkit.com/api/v1/shipments \
  -H "Authorization: Bearer $SERIAN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1234" \
  -d '{ "rate_id": "rt_abc123", "reference": "order-1234" }'

Step 4 — Listen for updates

Either poll GET /api/v1/tracking?tracking_number=..., or (much better) register a webhook. Events you can subscribe to:

  • shipment.created
  • shipment.updated
  • shipment.delivered
  • shipment.cancelled
  • tracking.updated
  • label.created

Every outgoing webhook is signed with HMAC-SHA256 using your endpoint’s secret. Verify it with:

typescript
import crypto from "crypto";

function verify(raw: string, signature: string, secret: string) {
  const expected = crypto.createHmac("sha256", secret).update(raw).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

Best practices

  • Idempotency: always send Idempotency-Key on POSTs. Responses are cached for 24 hours so retries are safe.
  • Rate limits: default 120 requests/minute per key. We return X-RateLimit-Remaining and Retry-After headers.
  • Error handling: non-2xx responses are JSON with error.code, error.message, and a request_id you can forward to support.
  • Test mode: never charges you and never moves real freight. Use it for your CI and staging environments.

Full API reference

See the API reference or fetch the machine-readable spec at /api/v1/openapi. SDK stubs for Node and Python live in packages/ in our GitHub repo.