WiriMarket Connect API

Push your menu in and receive orders out of WiriMarket using your own POS or restaurant management system — no need to run Wiri.

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

  1. Create a free WiriMarket owner account and add your restaurant, choosing "I use a different system".
  2. Subscribe to a Connect plan (Basic or Pro) — this activates your API access.
  3. Your restaurant's one-time webhook_secret and 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.
  4. 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:

PlanPer minutePer day
Basic605,000
Pro30050,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

StatusMeaning
401Missing, malformed, or invalid API token.
402No active Connect subscription — subscribe from your owner dashboard.
403This endpoint is only available to restaurants using a non-Wiri integration.
404The requested record doesn't exist, isn't yours, or was already processed.
422Validation failed — see the error message for specifics (e.g. over your plan's item limit).
429Rate 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/moPro — $99/outlet/mo
Menu itemsUp to 200Unlimited
Order retrievalWebhook or pull APIWebhook or pull API
Customer contact info per orderName, phone, delivery address
Rate limit60/min, 5,000/day300/min, 50,000/day
SupportStandardPriority

Get started or, if you already have a restaurant, manage your subscription.