Wahio Developers

Wahio Public API

Choose an endpoint from the navigation to view its contract and try a request.

Authentication

Requests that require authentication must include your API key in the X-Api-Key header. In the interactive playground, paste it into the Header section, which opens automatically on every endpoint. You can create and manage keys from the Public API settings in the Wahio app.

Account access, partial product editing and the replacement beta search contract are pending deployment. Read the Products and Inventory guide for search filters, facets, request examples and rollout status.

Orders and contacts in your account

Deployment pending: GET /v1/orders/{id} requires orders:read and retrieves an order only from the account associated with your API key. Put the order ID in the route. Do not send an account selector; a different account in a header, query or request body does not change the account from your key.

A matching order returns 200 with the existing order resource in snake_case, including its items, totals and shipment data. Unknown orders and orders outside your account return the same 404. Service or network failures remain errors, rather than being reported as missing orders. The API does not retry through an unscoped lookup.

The same account rule is now implemented locally for order creation, invoice creation, shipment status and contacts. These changes await deployment and remote validation. There is no public PUT or PATCH for general order editing; the generated endpoint reference reflects the published backend.

  • POST /v1/orders requires orders:write. Send organization_id, document_type and items; the API supplies the account from your key.
  • POST /v1/orders/{id}/invoice requires orders:write. Order and invoice numeration must belong to your account.
  • PUT /v1/shipments/{id}/status requires orders:write. Send status_id; shipment, parent order and target status must share your account.
  • GET /v1/contacts requires contacts:read. Query, page, page_size and sorting remain available; there is no account_id selector.
  • POST /v1/contacts requires contacts:write. Send first_name and optional contact/fiscal data; no account_id is needed.

Related contacts, products, variants and warehouse/product combinations in an order must be available in the authenticated account. IDs supplied for new item or shipment/address rows do not update another document. Missing or foreign resources return 404; invalid input returns 400. Missing authentication returns 401 and missing permission 403. Service failures remain errors, with no unscoped retry. New operations still use their existing business validations and events.

Usage limits

Deployment pending: the approved limit is 60 admitted requests per account and deployment environment in a rolling 60-second window. All API keys and protected operations for that account share the quota; creating or rotating a key does not increase it. Separate accounts have independent quotas. This is a usage limit, not a throughput guarantee.

Requests over quota return 429 Too Many Requests before the operation runs. The Retry-After header gives whole seconds to wait (1–60). After that wait, another client of the same account may still consume the next slot. The server does not queue or automatically retry your operation.

HTTP/1.1 429 Too Many Requests
Retry-After: 17
Cache-Control: no-store
Content-Type: application/json

{"error":"TooManyRequests","message":"The account has reached 60 requests in 60 seconds."}

An admitted request consumes quota even if its later validation or business operation fails. A stock batch counts as one HTTP request. Invalid authentication and missing permissions do not consume this quota; health, OpenAPI and outgoing webhook deliveries are separate. A per-key rate setting does not override the shared account quota.

If request admission is unavailable, the API returns 503 Service Unavailable before the operation runs. Other failures and timeouts may happen after saving: follow each operation’s reconciliation and retry rules before repeating a write. This limit does not make product creation or stock updates idempotent.

Testing and sandbox

There is no documented, validated self-service sandbox for integrators at this time. Internal development deployments are not an offered public sandbox. No sandbox URL, automatic reset or dry-run mode is provided here. Agree a test account and environment with Wahio before testing writes.

A pk_test_ prefix does not select an isolated backend, simulate a response or prevent writes. The server determines the key’s environment; you cannot select a sandbox with an environment field or header. A separate account in production still writes real production data.

The interactive playground sends real requests to the backend used by the published reference. Opening Developers on localhost does not change that backend. Confirm the target environment and use that test account’s key, product, warehouse and tax identifiers before sending a write. Fiscal test modes do not turn product or stock operations into simulations.

API routes update

These beta routes are implemented locally and await deployment and remote validation. They replace the previous routes without aliases. The endpoint navigation still reflects the OpenAPI contract published by the configured backend.

Updated routes pending deployment
RoutePurpose
POST /v1/products/stockUpdate product or variant stock; warehouse_id remains required in each update.
POST /v1/orders/{id}/invoiceCreate the commercial invoice for the order identified by the route.
PUT /v1/shipments/{id}/statusChange only the shipment’s status; this ID belongs to the shipment, not the order.
GET /v1/orders/{id}/electronic-documentRead the order’s fiscal document, result and available files.
POST /v1/orders/{id}/electronic-document/emitEmit the order’s electronic document using the existing Idempotency-Key flow.
GET /v1/billing/operation-modesList the account’s stored fiscal operation modes.
GET /v1/billing/resolutionsList the account’s stored fiscal resolutions.

For the invoice endpoint, the body contains order_invoice_numeration_id, optional account_user_id, payment_terms_days and payment. The order ID comes from the route, including the order link used by an optional payment.

{
  "order_invoice_numeration_id": "NUMERATION_ID",
  "payment_terms_days": 30
}

For shipment status, send only status_id. This replaces the status subresource and does not open arbitrary shipment editing.

{
  "status_id": "STATUS_ID"
}

See the stock guide and electronic billing guide for payloads, permissions and limitations. Resource names will remain stable after this beta is finalized; new capabilities will extend resource families, with incompatible changes requiring a new API version.

Example request

Replace the placeholders with an order ID and one of your API keys.

curl --request GET \
  --url 'https://api.wahio.com/api/v1/orders/ORDER_ID' \
  --header 'Accept: application/json' \
  --header 'X-Api-Key: YOUR_API_KEY'