Dawurobo Partner Platform

Get started with the Dawurobo delivery API

Start integrating the Dawurobo Partner Platform in Ghana — environments and base URLs, staging vs production, keys and scopes, and the signed request lifecycle.

You need an account to call anything

Create a Dawurobo partner account, self-upgrade to a partner (free, instant), and generate sandbox keys — then sign every request. Unauthenticated or unsigned calls return 401. The "Try it" in the API reference needs your own keys.

What you'll complete

  1. Create your partner app in Partner Hub.
  2. Generate a staging API key + signing secret.
  3. Implement request signing (see Authentication and signing).
  4. Send test traffic with your staging key (same base URLs as production).
  5. Request production activation once staging is verified end to end.
  6. Generate a production key and swap it in — the base URL doesn't change.

Base URLs and environments

There is one base URL per service — you use the same URL for staging and production:

ServiceBase URL
Deliveryhttps://delivery.dawurobo.com
Safe cataloghttps://safe.dawurobo.com

The environment lives on your API key, not the URL. Each key is a staging key or a production key, and that's what decides whether a request runs against staging or production. A sandbox (staging) key and a production key call the exact same endpoints — so when you go live you switch keys, not URLs. There is no separate staging host to configure.

All partner-platform endpoints live under a versioned, per-service path:

/api/v1/{service}/{operation}

For example (identical URL whether you send a staging or a production key — the key decides):

GET https://delivery.dawurobo.com/api/v1/delivery/health
GET https://safe.dawurobo.com/api/v1/safe-catalog/catalog.list

Staging vs production: what's actually callable

Staging keys are self-serve and instant — but they don't unlock every operation. Anything that moves real money is gated two ways: gateway-charging operations require a production key, and wallet-funded delivery orders additionally require the delivery:wallet:spend scope, which sandbox keys never carry. Everything else — auth, signing, reads, and standard (recipient-pays) delivery orders — works fully on staging.

OperationStagingProduction
delivery/health
delivery/orders.estimate, locations.list
delivery/orders.get, orders.track
delivery/orders.create, orders.cancel (recipient-pays / cash-on-delivery)
delivery/orders.create with payment.payer: "partner" (wallet-funded)❌ needs the delivery:wallet:spend scope — never on sandbox keys✅ with that scope
safe-catalog/catalog.list, catalog.get
safe-catalog/orders.get (read status)
delivery/wallet.balance, wallet.topup.initiate, wallet.topup.verify❌ production only
safe-catalog/orders.create, orders.verify❌ production only

In practice: you can build and fully test authentication, signing, catalog browsing, estimates, and the whole recipient-pays delivery order flow on staging before you ever request production access. Charging a payment gateway (wallet top-ups, prepaid Safe orders) needs a production key, and drawing down your wallet needs the delivery:wallet:spend scope — production activation is the approval + KYC step described above; see How money works for why.

Accounts, apps, and keys

Your partner account is organized in three levels:

Partner account (you / your company)
└── App (one per integration — e.g. "My Shop", "Client Pharmacy")
    └── API keys (per app, per environment) + webhook settings

You never send an app id on a request — your API key IS the app identity. Every key is minted inside one app, so when you call the API with that key, the platform already knows exactly which partner and which app is calling. Everything the call produces is stamped with that app.

Why apps matter — records never mix. Each app is an isolation boundary:

  • Orders created with one app's key are invisible to every other app's keys — even other apps under your own account. orders.get/orders.track/orders.cancel return 404 for anything the calling app didn't create.
  • Webhooks are configured per app, so each integration gets its own endpoint and signing secret.
  • Dashboard history, logs, and metrics are grouped per app.

So if you run several storefronts — or you're a developer/freelancer integrating delivery for multiple clients — create one app per storefront/client under your single account, mint keys per app, and each client's orders, webhooks, and logs stay cleanly separated. One login, many isolated integrations.

Create and manage apps in Partner Hub.

API keys

Keys are minted per app, per environment, and look like:

pk_staging_<random>   # staging
pk_production_<random> # production

Each key has its own signing secret (sk_...), shown once at creation time — store it in a secrets manager, not in source control. The signing secret is separate from the API key itself so you can rotate one without touching the other.

Scopes

Keys carry a list of scopes that gate which operations they can call: delivery:read, delivery:write, delivery:wallet:topup, delivery:wallet:spend, safe:read, safe:write.

Money scopes are exact-only. A delivery:* or * wildcard covers reads and standard writes, but never the money-moving scopes — delivery:wallet:topup (credits your wallet), delivery:wallet:spend (funds orders from your wallet), and safe:write (charges a buyer) must be granted to your key by name. Request only the scopes your integration needs.

Request lifecycle

Every authenticated request goes through, in order:

  1. API key resolutionX-API-Key (or Authorization: Bearer <key>) maps to a partner, app, and environment.
  2. Scope check — the resolved key must carry the operation's required scope.
  3. Partner status check — the partner account must be active.
  4. Signature verification — see Authentication and signing.
  5. Replay check — the X-Nonce must not have been seen before for this key.
  6. Rate limit — 120 req/min for reads, 60 req/min for writes, per key.

Any failure short-circuits with a 4xx and a machine-readable code — see Troubleshooting.

Try it

Full request/response schemas for every operation are in the API Reference — it's generated directly from the platform's OpenAPI spec, so it never drifts from what's actually deployed.