API Wiri Connect

Uma API REST orientada para leitura para extrair dados do Wiri para sistemas de terceiros, painéis e integrações. Disponível nos planos Enterprise.


Apenas Enterprise. A API Wiri Connect está disponível no plano Enterprise. Para gerar uma chave API, vá a Definições → Acesso API na sua conta Wiri.

Autenticação

Cada pedido deve incluir a chave API no cabeçalho Authorization como token Bearer:

# Exemplo com curl
curl https://app.wiri.food/api/v1/items \
  -H "Authorization: Bearer wk_sua_chave_api"

Se a chave estiver em falta ou for inválida, a API devolve 401 Unauthorized:

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

URL base

Todos os endpoints são servidos a partir da plataforma cloud Wiri:

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

Endpoints

MétodoEndpointDescrição
GET /api/v1/items Listar todos os artigos do menu
GET /api/v1/contacts Listar todos os clientes / contactos
GET /api/v1/invoices Listar faturas — suporta ?status, ?from, ?to
GET /api/v1/sales Listar vendas da caixa — suporta ?status, ?from, ?to
GET /api/v1/orders Listar encomendas do marketplace — suporta ?status, ?from, ?to
POST /api/v1/orders Criar uma encomenda de marketplace pré-paga
GET /api/v1/reservations Listar reservas futuras — suporta ?days, ?date
POST /api/v1/reservations Criar uma reserva de mesa a partir do marketplace

Formato de resposta

Todas as respostas bem-sucedidas devolvem 200 OK com um corpo JSON contendo dois campos:

{
  "data": [ /* array de objetos */ ],
  "count": 42
}

GET /api/v1/items

Devolve todos os artigos do menu da sua conta, ordenados alfabeticamente. Cada artigo inclui um array modifier_groups — os mesmos grupos/opções de modificadores configurados em Definições → Modificadores para esse artigo, para que possa apresentar e cobrar extras exatamente como configurados no Wiri.

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

# Resposta
{
  "data": [
    {
      "id": 1,
      "name": "Jollof Rice",
      "rate": "45.00",
      "unit": "plate",
      "description": null,
      "category": 3,
      "modifier_groups": [
        {
          "id": 2,
          "name": "Spice Level",
          "min_selections": 1,
          "max_selections": 1,
          "is_required": true,
          "options": [
            { "id": 5, "name": "Mild", "price": 0 },
            { "id": 6, "name": "Hot", "price": 0 }
          ]
        }
      ]
    }
  ],
  "count": 1
}

GET /api/v1/contacts

Devolve todos os contactos (clientes) da sua conta, ordenados por nome.

# Resposta
{
  "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

Devolve faturas ordenadas por data decrescente. Suporta os seguintes parâmetros de consulta:

ParâmetroTipoExemploDescrição
statusstringPaidPaid, Unpaid ou Overdue
fromdata2026-01-01Início do intervalo de datas (inclusive)
todata2026-01-31Fim do intervalo de datas (inclusive)
# Obter todas as faturas pagas de janeiro de 2026
curl "https://app.wiri.food/api/v1/invoices?status=Paid&from=2026-01-01&to=2026-01-31" \
  -H "Authorization: Bearer wk_..."

# Resposta
{
  "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

Devolve vendas da caixa ordenadas por data decrescente. Suporta os mesmos parâmetros que as faturas, com status aceitando paid ou voided.

# Obter todas as vendas de um dia
curl "https://app.wiri.food/api/v1/sales?from=2026-07-01&to=2026-07-01" \
  -H "Authorization: Bearer wk_..."

# Resposta
{
  "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

Devolve encomendas do marketplace (source = online) ordenadas por data decrescente, até 200 resultados. Suporta os mesmos parâmetros ?status, ?from e ?to que /api/v1/sales.

# Obter as encomendas de marketplace de hoje
curl "https://app.wiri.food/api/v1/orders?from=2026-07-01&to=2026-07-01" \
  -H "Authorization: Bearer wk_..."

# Resposta
{
  "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

Cria uma encomenda de marketplace pré-paga como uma venda de caixa com source=online e payment_status=paid. Devolve 201 Created em caso de sucesso.

Corpo do pedido

CampoTipoObrigatórioDescrição
branch_idintegerSimID da filial que recebe a encomenda
itemsarraySimLinhas de encomenda — pelo menos uma obrigatória (ver abaixo)
customer_namestringNãoNome de exibição do cliente
customer_phonestringNãoNúmero de telefone do cliente
delivery_addressstringNãoMorada de entrega (guardada nas notas da venda)
payment_methodstringNãoRótulo do pagamento, ex. card, mobile_money (guardado nas notas)
marketplace_refstringNãoA sua referência de encomenda — recomendado para reconciliação
tipnumberNãoValor da gorjeta, padrão 0
table_idintegerNãoMesa a associar à encomenda
coversintegerNãoNúmero de lugares / convidados, padrão 0

Objeto artigo

CampoTipoObrigatórioDescrição
item_idintegerNãoID do artigo no catálogo — omitir ou definir null para artigos não listados / personalizados
namestringSimNome do artigo tal como deve aparecer no recibo
qtynumberSimQuantidade, deve ser maior que 0
pricenumberSimPreço unitário, deve ser ≥ 0. Já deve incluir o ajuste de preço dos modificadores selecionados — é isto que é cobrado; modifiers abaixo é apenas um resumo de exibição/relatório
notestringNãoNota para a cozinha, ex. Extra spicy
modifiersarrayNãoResumo dos modificadores selecionados para o talão de cozinha / relatórios, ex. [{"name": "Large", "price_adjustment": 5.00}] — apenas informativo, não afeta o price cobrado
# Criar uma encomenda de marketplace
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": 40.00, "note": "Extra spicy",
        "modifiers": [{ "name": "Spicy", "price_adjustment": 5.00 }] },
      { "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
  }'

# Resposta 201
{
  "id": 142,
  "receipt_number": "MKT-000142",
  "total": 95.00,
  "status": "open"
}
Artigos não listados: Se item_id for omitido ou null, o artigo é guardado como uma linha personalizada na venda. Útil para extras, especiais ou artigos ainda não no seu catálogo.

GET /api/v1/reservations

Devolve reservas futuras com estado pending ou confirmed. Use ?days=N (padrão 7, máx. 90) para olhar N dias à frente, ou ?date=YYYY-MM-DD para uma única data.

# Obter reservas dos próximos 14 dias
curl "https://app.wiri.food/api/v1/reservations?days=14" \
  -H "Authorization: Bearer wk_..."

# Resposta
{
  "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

Cria uma reserva de mesa a partir do marketplace. Devolve 201 Created em caso de sucesso.

Corpo do pedido

CampoTipoObrigatórioDescrição
party_namestringSimNome do grupo / contacto da reserva
party_sizeintegerSimNúmero de convidados (deve ser ≥ 1)
datestringSimData da reserva no formato YYYY-MM-DD
timestringSimHora da reserva no formato HH:MM (24 horas)
branch_idintegerNãoFilial à qual atribuir a reserva
table_idintegerNãoMesa específica a reservar
duration_minsintegerNãoDuração esperada em minutos, padrão 90
notesstringNãoPedidos especiais ou notas
marketplace_refstringNãoA sua referência de reserva — recomendado para atualizações de estado
# Criar uma reserva
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"
  }'

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

Respostas de erro

Estado HTTPCorpoQuando
401{"error": "Invalid API key."}Chave em falta, errada ou revogada
401{"error": "Missing or malformed Authorization header."}Cabeçalho ausente ou não no formato Bearer
400{"error": "Invalid JSON body."}Corpo POST em falta ou JSON inválido
404{"error": "Unknown endpoint."}Nome de recurso não na lista permitida
405{"error": "Method not allowed."}Método HTTP errado para um endpoint apenas-POST
422{"error": "..."} ou {"errors": ["..."]}O corpo do pedido falhou a validação — ex. campo obrigatório em falta, filial/mesa não encontrada
500{"error": "Failed to create ... Please try again."}Erro inesperado do servidor ao guardar o pedido

Gerar uma chave API

  1. Inicie sessão na sua conta Wiri (plano Enterprise necessário).
  2. Vá a Definições → Acesso API.
  3. Clique em Gerar chave API. A chave começa com wk_.
  4. Copie a chave imediatamente — é mostrada na íntegra apenas uma vez após a geração.
  5. Para rodar a chave, clique em Regenerar chave. A chave antiga deixa de funcionar imediatamente.
Mantenha a chave secreta. Qualquer pessoa com a sua chave API pode ler todos os dados do seu negócio. Não a inclua em controlo de versão nem a exponha em código do lado do cliente.

Ver também: Definições · WiriMarket Connect (integração com PDV de terceiros)