Wiri Connect API

A read-oriented REST API for pulling your Wiri data into third-party systems, dashboards, and integrations. Available on Enterprise plans.


Enterprise only. The Wiri Connect API is available on the Enterprise plan. To generate an API key, go to Settings → API Access inside your Wiri account.

Authentication

Every request must include your API key in the Authorization header as a Bearer token:

# Example using curl
curl https://app.wiri.food/api/v1/items \
  -H "Authorization: Bearer wk_your_api_key_here"

If the key is missing or invalid, the API returns 401 Unauthorized:

{
  "error": "Invalid API key."
}

Base URL

All endpoints are served from the Wiri cloud platform:

https://app.wiri.food/api/v1/

Endpoints

MethodEndpointDescription
GET /api/v1/items List all menu items
GET /api/v1/contacts List all customers / contacts
GET /api/v1/invoices List invoices — supports ?status, ?from, ?to
GET /api/v1/sales List POS sales — supports ?status, ?from, ?to
GET /api/v1/orders List marketplace orders — supports ?status, ?from, ?to
POST /api/v1/orders Create a pre-paid marketplace order
GET /api/v1/reservations List upcoming reservations — supports ?days, ?date
POST /api/v1/reservations Create a marketplace table reservation

Response Format

All successful responses return 200 OK with a JSON body containing two fields:

{
  "data": [ /* array of objects */ ],
  "count": 42
}

GET /api/v1/items

Returns all menu items belonging to your account, ordered alphabetically.

# Request
curl https://app.wiri.food/api/v1/items \
  -H "Authorization: Bearer wk_..."

# Response
{
  "data": [
    {
      "id": 1,
      "name": "Jollof Rice",
      "rate": "45.00",
      "unit": "plate",
      "description": null,
      "category": 3
    }
  ],
  "count": 1
}

GET /api/v1/contacts

Returns all contacts (customers) belonging to your account, ordered by name.

# Response
{
  "data": [
    {
      "id": 12,
      "display_name": "Ama Owusu",
      "email": "ama@example.com",
      "mobile": "+233201234567",
      "address": null,
      "type": "individual",
      "created_at": "2026-01-15 09:22:00"
    }
  ],
  "count": 1
}

GET /api/v1/invoices

Returns invoices ordered by date descending. Supports the following query parameters:

ParameterTypeExampleDescription
statusstringPaidPaid, Unpaid, or Overdue
fromdate2026-01-01Start of date range (inclusive)
todate2026-01-31End of date range (inclusive)
# Fetch all paid invoices for January 2026
curl "https://app.wiri.food/api/v1/invoices?status=Paid&from=2026-01-01&to=2026-01-31" \
  -H "Authorization: Bearer wk_..."

# Response
{
  "data": [
    {
      "id": 88,
      "invoice_number": "INV-00088",
      "date": "2026-01-20",
      "due_date": "2026-02-03",
      "amount": "250.00",
      "tax": "37.50",
      "total": "287.50",
      "status": "Paid",
      "customer": "Ama Owusu"
    }
  ],
  "count": 1
}

GET /api/v1/sales

Returns POS sales ordered by date descending. Supports the same query parameters as invoices, with status accepting paid or voided.

# Fetch all sales for a day
curl "https://app.wiri.food/api/v1/sales?from=2026-07-01&to=2026-07-01" \
  -H "Authorization: Bearer wk_..."

# Response
{
  "data": [
    {
      "id": 201,
      "receipt_number": "RCP-00201",
      "date": "2026-07-01 13:45:00",
      "amount_due": "120.00",
      "payment_mode": "0",
      "covers": 3,
      "status": "paid",
      "voided_at": null,
      "voided_reason": null,
      "customer": null
    }
  ],
  "count": 1
}

GET /api/v1/orders

Returns marketplace orders (source = online) ordered by date descending, up to 200 results. Supports the same ?status, ?from, and ?to query parameters as /api/v1/sales.

# Fetch today's marketplace orders
curl "https://app.wiri.food/api/v1/orders?from=2026-07-01&to=2026-07-01" \
  -H "Authorization: Bearer wk_..."

# Response
{
  "data": [
    {
      "id": 142,
      "receipt_number": "MKT-000142",
      "marketplace_ref": "MKT-20260701-001",
      "date": "2026-07-01 12:30:00",
      "status": "open",
      "payment_status": "paid",
      "amount_due": "85.00",
      "tip": "5.00",
      "customer_name": "Jane Doe",
      "customer_phone": "+233241234567",
      "branch": "Main Branch"
    }
  ],
  "count": 1
}

POST /api/v1/orders

Creates a pre-paid marketplace order as a POS sale with source=online and payment_status=paid. Returns 201 Created on success.

Request body

FieldTypeRequiredDescription
branch_idintegerYesID of the branch receiving the order
itemsarrayYesLine items — at least one required (see below)
customer_namestringNoCustomer's display name
customer_phonestringNoCustomer's phone number
delivery_addressstringNoDelivery address (stored in the sale notes)
payment_methodstringNoPayment label, e.g. card, mobile_money (stored in notes)
marketplace_refstringNoYour platform's order reference — recommended for reconciliation
tipnumberNoGratuity amount, default 0
table_idintegerNoTable to associate the order with
coversintegerNoNumber of covers / guests, default 0

Item object

FieldTypeRequiredDescription
item_idintegerNoCatalogue item ID — omit or set null for unlisted / custom items
namestringYesItem name as it should appear on the receipt
qtynumberYesQuantity, must be greater than 0
pricenumberYesUnit price, must be ≥ 0
notestringNoKitchen note, e.g. Extra spicy
# Create a marketplace order
curl -X POST https://app.wiri.food/api/v1/orders \
  -H "Authorization: Bearer wk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "branch_id": 1,
    "items": [
      { "item_id": 5, "name": "Jollof Rice", "qty": 2, "price": 35.00, "note": "Extra spicy" },
      { "name": "Bottled Water", "qty": 2, "price": 5.00 }
    ],
    "customer_name": "Jane Doe",
    "customer_phone": "+233241234567",
    "delivery_address": "15 Independence Ave",
    "payment_method": "card",
    "marketplace_ref": "MKT-20260701-001",
    "tip": 5.00
  }'

# Response 201
{
  "id": 142,
  "receipt_number": "MKT-000142",
  "total": 85.00,
  "status": "open"
}
Unlisted items: If item_id is omitted or null, the item is saved as a custom line item on the sale. This is useful for add-ons, specials, or items not yet in your catalogue.

GET /api/v1/reservations

Returns upcoming reservations with status pending or confirmed. Use ?days=N (default 7, max 90) to look ahead N days, or ?date=YYYY-MM-DD to fetch a single date.

# Fetch reservations for the next 14 days
curl "https://app.wiri.food/api/v1/reservations?days=14" \
  -H "Authorization: Bearer wk_..."

# Response
{
  "data": [
    {
      "id": 23,
      "party_name": "Smith party",
      "party_size": 4,
      "reserved_date": "2026-07-15",
      "reserved_time": "19:30:00",
      "duration_mins": 90,
      "status": "pending",
      "source": "marketplace",
      "marketplace_ref": "MKT-RES-20260715-1",
      "notes": "Anniversary dinner",
      "table_name": "Table 4",
      "branch": "Main Branch"
    }
  ],
  "count": 1
}

POST /api/v1/reservations

Creates a table reservation from the marketplace. Returns 201 Created on success.

Request body

FieldTypeRequiredDescription
party_namestringYesName of the party / booking contact
party_sizeintegerYesNumber of guests (must be ≥ 1)
datestringYesReservation date in YYYY-MM-DD format
timestringYesReservation time in HH:MM format (24-hour)
branch_idintegerNoBranch to assign the reservation to
table_idintegerNoSpecific table to reserve
duration_minsintegerNoExpected duration in minutes, default 90
notesstringNoSpecial requests or notes
marketplace_refstringNoYour platform's booking reference — recommended for status updates
# Create a reservation
curl -X POST https://app.wiri.food/api/v1/reservations \
  -H "Authorization: Bearer wk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "party_name": "Smith party",
    "party_size": 4,
    "date": "2026-07-15",
    "time": "19:30",
    "branch_id": 1,
    "table_id": 3,
    "duration_mins": 90,
    "notes": "Anniversary dinner",
    "marketplace_ref": "MKT-RES-20260715-1"
  }'

# Response 201
{
  "id": 23,
  "status": "pending"
}

Error Responses

HTTP StatusBodyWhen
401{"error": "Invalid API key."}Key missing, wrong, or revoked
401{"error": "Missing or malformed Authorization header."}Header absent or not in Bearer format
404{"error": "Unknown endpoint."}Resource name not in allowed list

Generating an API Key

  1. Log in to your Wiri account (Enterprise plan required).
  2. Go to Settings → API Access.
  3. Click Generate API Key. Your key starts with wk_.
  4. Copy the key immediately — it is shown in full only once after generation.
  5. To rotate the key, click Regenerate Key. The old key stops working immediately.
Keep your key secret. Anyone with your API key can read all your business data. Do not commit it to version control or expose it in client-side code.

Related: Settings · Wiri Connect overview