WiriMarket Connect API
Overview
WiriMarket Connect is a REST API for restaurants using a POS or management system other than Wiri. It lets your system push a menu into WiriMarket and receive orders back, either by webhook or by polling — so your restaurant can appear on WiriMarket without switching software.
Already running Wiri? You don't need any of this — a Wiri restaurant's menu and orders sync automatically through your existing Wiri Connect API key instead. This page is specifically for a different system integrating directly.
Getting Started
- Create a free WiriMarket owner account and add your restaurant, choosing "I use a different system".
- Subscribe to a Connect plan (Basic or Pro) — this activates your API access.
- Your restaurant's one-time
webhook_secretand API token are shown once, right after you add it — copy them somewhere safe. You can regenerate either later from your restaurant's edit page if you lose them. - Push your menu (see below), then either configure your webhook URL to receive orders in real time, or poll the pull API instead.
Authentication
Every request must include your API token as a Bearer token:
curl https://wiri.market/api/v1/menu \
-H "Authorization: Bearer YOUR_API_TOKEN"
A missing or invalid token returns 401. Keep your token secret — anyone with it can read and replace your menu, and see your incoming orders.
Base URL
https://wiri.market/api/v1
Rate Limits
Requests are limited per restaurant, tiered by plan:
| Plan | Per minute | Per day |
|---|---|---|
| Basic | 60 | 5,000 |
| Pro | 300 | 50,000 |
Exceeding either limit returns 429 with a Retry-After header (seconds until you can try again):
HTTP/1.1 429 Too Many Requests
Retry-After: 42
{"error": "Rate limit exceeded. Try again in 42 seconds."}
Errors
| Status | Meaning |
|---|---|
401 | Missing, malformed, or invalid API token. |
402 | No active Connect subscription — subscribe from your owner dashboard. |
403 | This endpoint is only available to restaurants using a non-Wiri integration. |
404 | The requested record doesn't exist, isn't yours, or was already processed. |
422 | Validation failed — see the error message for specifics (e.g. over your plan's item limit). |
429 | Rate limit exceeded — see above. |
Menu
GET /api/v1/menu
Returns your current menu (all items, active and inactive).
{
"data": [
{"id": 12, "name": "Jollof Rice", "rate": 45.00, "description": "Smoky jollof", "category": "Mains"}
],
"count": 1
}
POST /api/v1/menu
Full replace — this becomes your entire menu. Anything not included is removed, the same idea as a full cache repopulation rather than an incremental diff.
POST /api/v1/menu
{
"items": [
{
"name": "Jollof Rice",
"rate": 45.00,
"description": "Smoky jollof",
"category": "Mains",
"is_active": true
}
]
}
name and rate (≥ 0) are required; description, category, and is_active (default true) are optional. Response is the same shape as GET. Connect Basic is limited to 200 items — exceeding it returns 422.
Orders
GET /api/v1/orders
Paid orders not yet acknowledged — an alternative to receiving the push webhook, for restaurants that prefer to poll.
{
"data": [
{
"event": "order.created",
"marketplace_ref": "3f9c1a...",
"fulfillment_type": "delivery",
"items": [{"name": "Jollof Rice", "qty": 2, "price": 45.00, "modifiers": []}],
"subtotal": 90.00,
"delivery_fee": 0,
"discount_amount": 0,
"total": 90.00,
"currency": "GHS",
"notes": null,
"created_at": "2026-08-03 12:00:00"
}
],
"count": 1
}
Connect Pro plans also get a "customer" field ({name, phone, delivery_address}) on each order — not included on Basic. A Basic-plan restaurant still gets a fully fulfillable pickup order (item list and amounts); missing customer contact details on delivery orders is a real, known limitation of that tier, not a bug.
POST /api/v1/orders
Acknowledge receipt of an order once it has reached your system.
POST /api/v1/orders
{
"marketplace_ref": "3f9c1a...",
"external_order_id": "your-own-id-42"
}
marketplace_ref is required (the order's reference from GET /api/v1/orders or your webhook payload); external_order_id is optional, your own system's id for the order. Acknowledging an already-processed or unknown order returns 404 — this is idempotent, so a retried acknowledgement is safe.
Webhook Push (Alternative to Polling)
Instead of polling GET /api/v1/orders, configure a webhook URL to receive orders the moment they're paid. WiriMarket POSTs the same payload shape shown above to your URL, signed with HMAC-SHA256 over the raw request body using your restaurant's webhook secret:
X-Wiri-Market-Signature: sha256=<hex-encoded HMAC>
Verify it before trusting the payload:
$expected = hash_hmac('sha256', $rawBody, $yourWebhookSecret);
$valid = hash_equals($expected, str_replace('sha256=', '', $signatureHeader));
Your endpoint should acknowledge with a 2xx response — anything else is treated as delivery failure.
Plans
| Basic — $49/outlet/mo | Pro — $99/outlet/mo | |
|---|---|---|
| Menu items | Up to 200 | Unlimited |
| Order retrieval | Webhook or pull API | Webhook or pull API |
| Customer contact info per order | — | Name, phone, delivery address |
| Rate limit | 60/min, 5,000/day | 300/min, 50,000/day |
| Support | Standard | Priority |
Get started or, if you already have a restaurant, manage your subscription.