Beta Delivery Zone is in private beta — now accepting select Finnish merchants.
Developer documentation

Delivery Zone API.

One authenticated endpoint. Send a postcode and basket value — get back a clear delivery decision, zone, price, and reason code.

POST/api/v1/delivery/check

Public Delivery Check API Contract

This API is used by external systems (custom backends, checkouts, or ERPs) to check if a postcode is deliverable based on your configured delivery zones and rules.

[!WARNING]

Permitted use — real-time validation only.

API responses must not be stored, cached, bulk-collected, exported, resold, or used to

create, enrich, reconstruct, or replace any postcode, address, distance, delivery-zone,

geographic, or similar dataset. Automated scraping, systematic enumeration, or bulk

querying of the API is prohibited. Full restrictions: API Terms of Use

and Acceptable Use Policy.

[!NOTE]

The Finland postcode dataset is centrally managed by Gn-Projects / Delivery Zone.

Customers do not upload, export, or download raw postcode data.

The API returns delivery decisions based on this central dataset and your specific zone rules.

>

Postcode validity is checked against authoritative Finnish postcode reference information.

For radius (distance-based) zones, the API uses a representative location for the postcode

and calculates straight-line distance from your configured base location — see the

Postcode Data Disclaimer for details and known limitations.

Endpoint

POST /api/v1/delivery/check

Headers

  • X-Api-Key: Your public API key.
  • Content-Type: application/json

Request Body

{
  "destinationPostcode": "00100",
  "basketValueCents": 4500
}

Success Responses (200 OK)

A 200 OK is returned for any valid check that completes, regardless of whether delivery is possible.

Deliverable

{
  "canDeliver": true,
  "matchedZoneName": "Helsinki Center",
  "priceCents": 590,
  "currency": "EUR",
  "estimatedDeliveryMinutes": 45,
  "reasonCode": "DELIVERABLE",
  "reasonMessage": "Delivery is available."
}

Not Deliverable

{
  "canDeliver": false,
  "reasonCode": "NOT_DELIVERABLE",
  "reasonMessage": "Delivery is not available for this postcode."
}

Not Deliverable — Minimum Order Not Met

{
  "canDeliver": false,
  "reasonCode": "MINIMUM_ORDER_NOT_MET",
  "reasonMessage": "The location is covered, but the minimum order value was not met.",
  "requiredBasketValueCents": 5000,
  "providedBasketValueCents": 3200,
  "shortfallCents": 1800
}

[!NOTE]

All non-deliverable outcomes that relate to postcode coverage or zone configuration

return the generic NOT_DELIVERABLE reason code. This is intentional.

Internal zone identifiers, raw distances, and postcode dataset membership signals are

never included in the public API response.

Error Responses

400 Bad Request

The request was malformed, the postcode format was invalid, or the basket value was invalid or missing when a matched rule required it.

{
  "canDeliver": false,
  "reasonCode": "INVALID_POSTCODE",
  "reasonMessage": "The postcode must be exactly 5 digits."
}

Other 400 reason codes: INVALID_BASKET_VALUE (negative basket value) and BASKET_VALUE_REQUIRED (the matched zone has a minimum-order or free-delivery rule and no basket value was provided — canDeliver is null in this case, and the response includes minimumOrderCents/freeDeliveryFromCents).

401 Unauthorized

{
  "error": "A valid API key is required."
}

403 Forbidden

The API key is valid but not permitted to access this endpoint (scope, organisation, or subscription state).

{
  "canDeliver": false,
  "reasonCode": "API_ACCESS_DENIED",
  "reasonMessage": "The API key is not permitted to access this endpoint."
}

405 Method Not Allowed

Returned for any HTTP method other than POST on this endpoint.

413 Payload Too Large

{
  "canDeliver": false,
  "reasonCode": "PAYLOAD_TOO_LARGE",
  "reasonMessage": "Request body exceeds the maximum allowed size."
}

429 Too Many Requests

Covers three distinct limits, distinguished by reasonCode. All three should be handled with exponential back-off and by respecting the Retry-After header.

Per-minute rate limit — temporary; no plan change required:

{
  "canDeliver": false,
  "reasonCode": "RATE_LIMITED",
  "reasonMessage": "Too many requests. Please try again later."
}

Daily limit (per API key) — resets at the next UTC midnight; distinct from the monthly quota and does not consume it:

{
  "canDeliver": false,
  "reasonCode": "DAILY_LIMIT_EXCEEDED",
  "reasonMessage": "This API key's daily request limit has been reached. Please wait for it to reset or use a different key.",
  "limitScope": "daily",
  "limit": 10000,
  "currentUsage": 10000,
  "resetAt": "2026-09-01T00:00:00.000Z"
}

Monthly plan quota — resets at the start of your next billing period. Do not retry automatically until your quota resets or your plan is upgraded:

{
  "canDeliver": false,
  "reasonCode": "PLAN_LIMIT_EXCEEDED",
  "reasonMessage": "Your plan's monthly API quota has been exhausted. Please upgrade your plan or wait for your quota to reset.",
  "limitScope": "monthly",
  "limit": 10000,
  "currentUsage": 10000,
  "resetAt": "2026-09-15T00:00:00.000Z"
}

503 Service Unavailable

The system is currently unable to process requests (e.g. no active central dataset).

{
  "canDeliver": false,
  "reasonCode": "NO_ACTIVE_DATASET",
  "reasonMessage": "Service temporarily unavailable."
}

Authentication

All requests require an X-Api-Key header. Get your key by creating a free account. Keys are organisation-scoped and can be rotated from the dashboard. There is no separate test/live environment — use a non-production delivery zone to test safely against your real API key.

Rate limits

API keys are limited to 120 requests per minute and 10,000 requests per day by default. Monthly quotas depend on your plan — see Pricing for the exact limits; the Free plan allows 10 checks per month. Exhausting your monthly quota, your daily limit, or your per-minute rate all return HTTP 429 Too Many Requests, distinguished by reasonCode (PLAN_LIMIT_EXCEEDED, DAILY_LIMIT_EXCEEDED, or RATE_LIMITED) — back off and retry per the Retry-After header; for plan/daily limits, wait for the reset shown in resetAt or upgrade your plan.