REST API · Beta

API Documentation

Integrate wallmarkets into your applications. Manage deliveries, returns, products, and supermarkets programmatically.

The API is in beta. Endpoints and response formats may change. Pin your integration to a specific API version to avoid surprises.

Introduction

The wallmarkets API lets you programmatically manage deliveries, returns, products, and supermarket accounts. All endpoints return JSON and require authentication via API key.

Base URL

https://www.wallmarkets.store/api/v1

Response Format

Every response includes a status field and a data payload (or an error object on failure).

{
  "status": "success",
  "data": { ... }
}

Authentication

Authenticate every request by including your API key as a Bearer token in the Authorization header.

Generating API Keys

Create keys in Account Settings > API Keys. Each key supports:

  • Scopes: Restrict access per resource (e.g. deliveries:read, returns:write, products:read)
  • Expiry: Optional expiration date — expired keys are rejected automatically
  • Rotation: Rotate a key to get a new secret without changing the key ID
Keys are hashed server-side (SHA-256). Copy the key immediately after creation — you will not be able to view it again.

Authentication Header

Authorization: Bearer YOUR_API_KEY

Example Request

curl -X GET \
  https://www.wallmarkets.store/api/v1/deliveries \
  -H 'Authorization: Bearer wm_live_abc123...'

Rate Limits

Rate limits protect service stability. Limits vary by plan:

Limits by Plan

API Plan Hourly Request Limit Minute Burst Limit
Free 60 requests/hour 10 requests/minute
Pro 1,000 requests/hour 60 requests/minute
Business 10,000 requests/hour 300 requests/minute

Rate Limit Headers

Every response includes these headers:

  • X-RateLimit-Limit: Max requests per hour
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: UTC epoch seconds when the window resets

Deliveries API

Scope required: deliveries:read / deliveries:write

List Deliveries

GET /api/v1/deliveries

Returns a paginated list of deliveries for the authenticated user.

# Query Parameters
?page=1&per_page=20&status=pending&date_from=2024-01-01&supermarket_id=5

Get a Delivery

GET /api/v1/deliveries/{delivery_id}
{
  "id": 123,
  "supermarket_name": "E-mart",
  "subchain_name": "Sukhbaatar Branch",
  "products": [
    {"product_id": 8, "name": "Product A", "quantity": 10, "unit_price": 5000},
    {"product_id": 15, "name": "Product B", "quantity": 5, "unit_price": 12000}
  ],
  "total_value": 110000,
  "delivery_date": "2024-10-15",
  "status": "completed",
  "created_at": "2024-10-01T10:30:00Z"
}

Create a Delivery

POST /api/v1/deliveries
{
  "supermarket_id": 5,
  "subchain_id": 12,
  "products": [
    {"product_id": 8, "quantity": 10},
    {"product_id": 15, "quantity": 5}
  ],
  "delivery_date": "2024-10-20",
  "notes": "Urgent delivery"
}

Update Delivery Status

PATCH /api/v1/deliveries/{delivery_id}
{
  "status": "completed"
}

Valid transitions: pending → in_transit → completed, or pending → cancelled.

Returns API

Scope required: returns:read / returns:write

List Returns

GET /api/v1/returns

Returns a paginated list. Filter by delivery, supermarket, reason, or date range.

# Query Parameters
?page=1&per_page=20&reason=damaged&delivery_id=123

Create a Return

POST /api/v1/returns
{
  "delivery_id": 123,
  "product_id": 8,
  "quantity": 3,
  "reason": "damaged",
  "return_date": "2024-10-18",
  "description": "Products arrived damaged during transit"
}

Get a Return

GET /api/v1/returns/{return_id}
{
  "id": 42,
  "delivery_id": 123,
  "product_id": 8,
  "product_name": "Product A",
  "quantity": 3,
  "reason": "damaged",
  "description": "Products arrived damaged during transit",
  "return_date": "2024-10-18",
  "credit_amount": 15000,
  "created_at": "2024-10-18T09:15:00Z"
}

Products API

Scope required: products:read / products:write

List Products

GET /api/v1/products

Returns all products for the authenticated user. Filter by category or search by name.

# Query Parameters
?page=1&per_page=50&category=Dairy&search=milk

Get a Product

GET /api/v1/products/{product_id}
{
  "id": 8,
  "sequential_id": "P-0008",
  "name": "Whole Milk 1L",
  "weight": 1.05,
  "price": 5000,
  "category": "Dairy",
  "created_at": "2024-08-01T12:00:00Z"
}

Create a Product

POST /api/v1/products
{
  "name": "Whole Milk 1L",
  "weight": 1.05,
  "price": 5000,
  "category": "Dairy"
}

A unique sequential_id is assigned automatically.

Update a Product

PATCH /api/v1/products/{product_id}
{
  "price": 5500
}

Only the fields you include are updated. Historical delivery records are not affected.

Supermarkets API

Scope required: supermarkets:read / supermarkets:write

List Supermarkets

GET /api/v1/supermarkets
[
  {
    "id": 5,
    "name": "E-mart",
    "branches": [
      {"id": 12, "name": "Sukhbaatar Branch", "address": "..."},
      {"id": 13, "name": "Bayangol Branch", "address": "..."}
    ]
  }
]

Get a Supermarket

GET /api/v1/supermarkets/{supermarket_id}

Returns the supermarket details including all branches, delivery windows, and contact info.

Create a Supermarket

POST /api/v1/supermarkets
{
  "name": "E-mart",
  "contact_email": "buyer@emart.mn",
  "branches": [
    {
      "name": "Sukhbaatar Branch",
      "address": "Peace Avenue 15, UB",
      "delivery_window": "08:00-12:00"
    }
  ]
}

Webhooks

Subscribe to webhooks to receive real-time HTTP callbacks when events occur. Webhooks are automatically deactivated after 10 consecutive delivery failures.

Event Types

Webhook Event Callback Meaning
delivery.created A new delivery was created
delivery.in_transit A delivery was dispatched
delivery.completed A delivery was marked as completed
delivery.cancelled A delivery was cancelled
return.created A new return was processed
product.created A new product was added
product.updated A product was modified

Webhook Payload Example

{
  "event": "delivery.completed",
  "timestamp": "2024-10-15T14:30:00Z",
  "data": {
    "delivery_id": 123,
    "supermarket_name": "E-mart",
    "subchain_name": "Sukhbaatar Branch",
    "total_value": 110000,
    "completed_at": "2024-10-15T14:30:00Z"
  }
}

Retry Policy

Failed deliveries are retried with exponential backoff (1 min, 5 min, 30 min). After 10 consecutive failures, the subscription is automatically deactivated. Re-enable it from your webhook settings.

Error Handling

HTTP Status Codes

HTTP Code Response State Developer Meaning
200 OK Request succeeded
201 Created Resource created successfully
400 Bad Request Invalid or missing parameters
401 Unauthorized Missing, invalid, or expired API key
403 Forbidden Key lacks the required scope for this endpoint
404 Not Found Resource does not exist or does not belong to you
429 Too Many Requests Rate limit exceeded — check X-RateLimit-Reset header
500 Internal Server Error Something went wrong on our end — retry or contact support

Error Response Format

{
  "status": "error",
  "error": {
    "code": "validation_error",
    "message": "delivery_date must be in the future",
    "field": "delivery_date"
  }
}

Ready to Get Started?

Generate your API keys and start integrating wallmarkets into your applications.