DEVELOPER API · V1

Your business.
Your connected tools.

Read your catalogue and business records, check booking availability and capture reservation requests through a scoped API.

Your first request
GET /api/v1/menu
Authorization: Bearer <your-token>
Accept: application/json

{
  "data": [
    { "category": "Mains", "items": […] }
  ]
}

One business per token. JSON responses.

01 / GET CONNECTED

Start with a menu request

  1. Enable the Developer API add-on for your business.
  2. In your business admin, open Settings → API Tokens. Create a token with catalog:read and copy it when shown.
  3. Call the API from your server or automation tool. Keep the token out of public websites and source control.

Examples use this application's host, so you can copy them for local testing. Replace the token placeholder in your own terminal.

curl 'https://servedhq.com/api/v1/menu' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

There is no built-in API sandbox. Use a dedicated test business locally. Reservation creation can send notifications or create a deposit checkout; configure test mail and payment credentials before experimenting.

Authentication & access

Every operation requires Authorization: Bearer <your-token>. The token selects the business; you do not pass a business ID. The business must be active and its Developer API add-on enabled.

ScopePermitsAdditional add-on
catalog:readRead the default menuNone
orders:readList and read ordersOnline Ordering
reservations:readList and read reservationsReservations
reservations:createRead bookable services, check slots and create reservationsReservations

Use the smallest set of scopes needed. Tokens can have an expiry date and can be revoked by deleting them in the admin. Legacy tokens with no stored scopes retain read permissions only.

Rate limit: 60 requests per minute. On a 429 response, wait for the Retry-After interval before retrying.

02 / AGENT WORKFLOW

From availability to a booking request

Use service IDs and option IDs returned by the catalogue. Check a date in the business's local timezone, then confirm the service, time and customer details with the customer before submitting.

Served HQ calculates prices and duration and checks availability again when you submit. A slot response is not a reservation or a guaranteed hold.

Groups: pass party_size when checking slots. Some businesses can see only a set number of people per time slot; a larger group then needs back-to-back slots, and only start times where the whole run is free are returned. Service prices are per person: each created line reports quantity and unit_price_pence, with price_pence as the line total. Restaurant table bookings are not priced per person.

Read the outcome before responding to the customer

201 means a reservation was created in pending state, awaiting review. 202 with payment_required returns a checkout_url for a deposit; the reservation has not yet been created. Neither result means a confirmed appointment.

Some services are enquiry-only and have no booked date. Home visits may require a service address, and businesses may require custom fields. Respect service-specific rules and validation errors.

Use a unique Idempotency-Key for each booking attempt. Reuse it with the same body for network retries. Reusing the key with a changed body returns a conflict.

03 / REFERENCE

Available endpoints

All paths below are relative to this application's host. Monetary fields ending in _pence are integer minor-unit amounts; interpret them using your business currency.

8 endpoints

GET/api/v1/menu

Get the business menu

Returns the authenticated business's default menu grouped by category. An empty `data` array is returned when no default menu exists. Only available fields are returned; this is not a complete catalogue or public discovery contract.

Scope: catalog:readAdd-on: Developer API only

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/menu' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Menu returned successfully

Schema: MenuResponse

Populated example

{
    "data": [
        {
            "category": "Mains",
            "items": [
                {
                    "id": 42,
                    "name": "Chickpea curry",
                    "description": "Tomato, ginger and toasted cumin",
                    "price_pence": 1250,
                    "is_available": true
                }
            ]
        }
    ]
}

Empty example

{
    "data": []
}
401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

GET/api/v1/orders

List orders

Returns orders belonging to the authenticated business. Results are ordered newest first and paginated. `since` accepts a date or timestamp understood by the application.

Scope: orders:readAdd-on: Online ordering

Parameters

NameLocationDetails
per_pagequeryNumber of records per page. integer. Min: 1. Max: 100. Default: 25.
pagequeryOne-based page number. integer. Min: 1. Default: 1.
statusqueryFilter by order status. string. Max length: 40.
sincequeryReturn orders created at or after this date or timestamp. string (date-time).

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/orders' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Paginated orders

Schema: OrderListResponse

401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
422 Invalid query parameter or request body

Schema: ValidationError

{
    "message": "The given data was invalid.",
    "errors": {
        "per_page": [
            "The per page field must be at least 1."
        ]
    }
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

GET/api/v1/orders/{order}

Get an order

Returns one order belonging to the authenticated business.

Scope: orders:readAdd-on: Online ordering

Parameters

NameLocationDetails
orderrequiredpathNumeric order identifier. integer (int64). Min: 1.

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/orders/123' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Order returned successfully

Schema: OrderResponse

401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
404 Resource does not exist for this business

Schema: Error

{
    "message": "No query results for model [App\\\\Models\\\\Order]."
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

GET/api/v1/services

List bookable services

Returns the public, available services and their option groups for booking.

Scope: reservations:createAdd-on: Reservations

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/services' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Bookable services

Schema: ServiceListResponse

401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

GET/api/v1/availability

List available booking slots

Returns slots calculated for the selected services on a business-local date. When the business sets a number of people per time slot, a group larger than that capacity needs one run of the services per wave of people, back to back within one shift (for example 3 people at 2 per slot need two consecutive runs). Only start times where every run fits are returned. Omitting party_size checks availability for one person, which matches the behaviour before contract 1.1.0.

Scope: reservations:createAdd-on: Reservations

Parameters

NameLocationDetails
daterequiredquery string (date).
menu_item_idsqueryMenu item IDs whose combined duration should be checked. array. Max items: 20.
party_sizequeryNumber of people to fit (added in 1.1.0). Defaults to 1. integer. Min: 1. Max: 50. Default: 1.

Encode service arrays as menu_item_ids[]=42&menu_item_ids[]=43. Date and time values are business-local; select a date within that business's booking window.

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/availability?date=2026-10-14&menu_item_ids%5B%5D=42' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Available slots

Schema: AvailabilityResponse

401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
422 Invalid query parameter or request body

Schema: ValidationError

{
    "message": "The given data was invalid.",
    "errors": {
        "per_page": [
            "The per page field must be at least 1."
        ]
    }
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

GET/api/v1/reservations

List reservations

Returns reservations belonging to the authenticated business. Results are ordered by reserved date and time. Enquiry-only records may have a null reserved date and are identified by `is_enquiry_only`.

Scope: reservations:readAdd-on: Reservations

Parameters

NameLocationDetails
per_pagequeryNumber of records per page. integer. Min: 1. Max: 100. Default: 25.
pagequeryOne-based page number. integer. Min: 1. Default: 1.
statusqueryFilter by reservation status. string. Max length: 40.
fromqueryReturn reservations on or after this business date. string (date).

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/reservations' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Paginated reservations

Schema: ReservationListResponse

401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
422 Invalid query parameter or request body

Schema: ValidationError

{
    "message": "The given data was invalid.",
    "errors": {
        "per_page": [
            "The per page field must be at least 1."
        ]
    }
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

POST/api/v1/reservations

Create a reservation

Creates a pending reservation after validating the selected public services, option selections, booking window, business ownership of a staff member, and slot availability. The client must send a unique Idempotency-Key. Repeating the same request with the same key replays the original response; reusing a key with a different body is a 409. Prices and duration supplied by a client are ignored. From contract 1.1.0, services are priced per person: each item's price_pence is the unit price (service plus selected options) times party_size, reported as quantity and unit_price_pence. Restaurant table bookings are not priced per person. When the business sets a number of people per time slot, total_duration_minutes covers every back-to-back run the group needs and the whole run must be free; otherwise the request fails with slot_unavailable. Deposits that a business sets per service are taken per person.

Scope: reservations:createAdd-on: Reservations

Parameters

NameLocationDetails
Idempotency-KeyrequiredheaderA client-generated key reused for safe retries of the same request. string. Max length: 255.

JSON request body

FieldTypeDetails
customer_namerequired string Max length: 150.
customer_emailrequired string Format: email. Max length: 255.
customer_phone string Max length: 30.
attendee_name string Max length: 150.
attendee_phone string Max length: 30.
service_name string Max length: 150.
service_address string Max length: 500.
party_sizerequired integer Minimum: 1.
reserved_date string Format: date.
reserved_time string Pattern: ^\\d{2}:\\d{2}$.
staff_member_id integer
notes string Max length: 500.
custom_field_values object
marketing_consent boolean
service_items array <ReservationServiceSelection> Max items: 20.

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl -X POST 'https://servedhq.com/api/v1/reservations' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <unique-booking-key>' \
  --data '{
    "customer_name": "Alex Morgan",
    "customer_email": "[email protected]",
    "customer_phone": "+447700900123",
    "party_size": 2,
    "reserved_date": "2026-10-14",
    "reserved_time": "18:30",
    "service_items": [
        {
            "menu_item_id": 42,
            "selected_options": [
                {
                    "group_id": 7,
                    "option_ids": [
                        12
                    ]
                }
            ]
        }
    ]
}'

Responses

201 Reservation created in pending state

Schema: ReservationResponse

202 Deposit payment is required before the reservation is created

Schema: PaymentRequiredResponse

400 Missing or invalid Idempotency-Key header

Schema: Error

{
    "error": "The Idempotency-Key header is required and must be 255 characters or fewer.",
    "code": "idempotency_key_required"
}
401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
409 Slot, idempotency, or booking state conflict

Schema: Error

{
    "error": "The requested booking slot is no longer available.",
    "code": "slot_unavailable"
}
422 Invalid query parameter or request body

Schema: ValidationError

{
    "message": "The given data was invalid.",
    "errors": {
        "per_page": [
            "The per page field must be at least 1."
        ]
    }
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

GET/api/v1/reservations/{reservation}

Get a reservation

Returns one reservation belonging to the authenticated business.

Scope: reservations:readAdd-on: Reservations

Parameters

NameLocationDetails
reservationrequiredpath integer (int64). Min: 1.

Request example

Illustrative IDs and customer details. Replace them with your test business's data. Shell syntax shown for Bash / Git Bash; on Windows use curl.exe and adapt line continuations for your shell.

curl 'https://servedhq.com/api/v1/reservations/123' \
  -H 'Authorization: Bearer <your-token>' \
  -H 'Accept: application/json'

Responses

200 Reservation returned successfully

Schema: ReservationResponse

401 Missing, invalid, revoked, or expired token

Schema: Error

{
    "error": "Invalid or expired API token."
}
403 Business, entitlement, or scope access denied

Schema: Error

InsufficientScope example

{
    "error": "Token does not permit this action.",
    "code": "insufficient_scope"
}

CapabilityDisabled example

{
    "error": "Required API capability is not enabled.",
    "code": "capability_disabled"
}

BusinessDisabled example

{
    "error": "Business access is disabled.",
    "code": "business_disabled"
}
404 Resource does not exist for this business

Schema: Error

{
    "message": "No query results for model [App\\\\Models\\\\Order]."
}
429 More than 60 requests in one minute

Schema: Error

Response headers: Retry-After

04 / EVENT DELIVERY

Webhooks: react to business changes

Served HQ sends an HTTP POST to your receiver when a subscribed event happens. Use it to notify an agent, update a connected dashboard or trigger your automation without polling.

Set up a subscription

  1. Enable the business's Developer API add-on and open Webhooks in the business admin.
  2. Add your public HTTPS receiver URL and select the events to receive.
  3. Copy the subscription's signing secret from the admin and store it on your receiver's server. This is separate from your API bearer token.
  4. Run the Served HQ queue worker and trigger a change using a test business. Check the subscription's last delivery status in the admin.

Destinations must use a public HTTPS hostname on port 443 that resolves to public IPv4 addresses. Localhost, private IPs, IPv6-only destinations and redirects are not supported. For local receiving experiments, use a public HTTPS tunnel to your test receiver; never disable destination validation.

What arrives at your endpoint

HeaderMeaning
Content-Typeapplication/json
X-ServedHQ-EventThe event name, also present in the signed body.
X-ServedHQ-TimestampUnix timestamp in seconds for this delivery attempt.
X-ServedHQ-Signature-V2Lowercase hex HMAC-SHA256 of timestamp + "." + raw body, using the subscription secret. Recommended.
X-ServedHQ-SignatureLegacy lowercase hex HMAC-SHA256 of the raw body only. It does not bind the delivery timestamp.

The JSON envelope contains event, id (UUID), timestamp (ISO 8601 event time) and data. The body and event ID stay the same across retries; the delivery timestamp header and V2 signature are regenerated. Validate freshness against the header timestamp, not the event timestamp in the body.

Events & payload examples

These are illustrative payloads, not a live delivery log. Events contain a subset of record fields. Use the matching GET order or reservation endpoint with its read scope and add-on to retrieve more details.

order.created — Order created

A new order was created. status is the creation status; this event does not assert that the order is paid.

{
    "event": "order.created",
    "id": "f41e0981-349d-4ef4-9c01-37a66fa272d3",
    "timestamp": "2026-10-06T12:00:00+00:00",
    "data": {
        "order_id": 123,
        "status": "pending",
        "total_pence": 2450,
        "customer_name": "Alex Morgan",
        "order_type": "collection"
    }
}
order.status_updated — Order status updated

An order's fulfilment status changed. Values include pending, confirmed, preparing, ready, completed and cancelled. This event does not report payment changes.

{
    "event": "order.status_updated",
    "id": "f41e0981-349d-4ef4-9c01-37a66fa272d3",
    "timestamp": "2026-10-06T12:00:00+00:00",
    "data": {
        "order_id": 123,
        "old_status": "confirmed",
        "new_status": "preparing"
    }
}
reservation.created — Reservation created

A reservation record was created. This is not a confirmation event. Enquiry-only records may have a null date and time. service_items may be empty; item IDs and durations may be null for some records.

{
    "event": "reservation.created",
    "id": "f41e0981-349d-4ef4-9c01-37a66fa272d3",
    "timestamp": "2026-10-06T12:00:00+00:00",
    "data": {
        "reservation_id": 456,
        "customer_name": "Alex Morgan",
        "reserved_date": "2026-10-07",
        "reserved_time": "10:30",
        "party_size": 1,
        "service_items": [
            {
                "menu_item_id": 42,
                "service_name": "Consultation",
                "duration_minutes": 30
            }
        ]
    }
}
reservation.confirmed — Reservation confirmed

The reservation was confirmed. Retrieve its date, time and services using the reservation ID.

{
    "event": "reservation.confirmed",
    "id": "f41e0981-349d-4ef4-9c01-37a66fa272d3",
    "timestamp": "2026-10-06T12:00:00+00:00",
    "data": {
        "reservation_id": 456,
        "customer_name": "Alex Morgan"
    }
}
reservation.cancelled — Reservation cancelled

The reservation was cancelled. The cancellation reason can be null.

{
    "event": "reservation.cancelled",
    "id": "f41e0981-349d-4ef4-9c01-37a66fa272d3",
    "timestamp": "2026-10-06T12:00:00+00:00",
    "data": {
        "reservation_id": 456,
        "customer_name": "Alex Morgan",
        "reason": "Customer requested cancellation"
    }
}

No dedicated stock-change, payment-settled, refund or reservation-rescheduled event is currently offered. Subscription creation, pausing and deletion happen in the admin; they are not API operations.

Verify the signature

Read the raw HTTP body before decoding JSON. Check the timestamp is within five minutes of your server's clock, calculate the V2 HMAC and compare in constant time. Changing whitespace or re-encoding the JSON before verification will invalidate the signature.

PHP example: pass $request->getContent(), the timestamp and V2 headers, and your stored secret to this function. Reject invalid requests before applying any business changes. Use the event name in the signed body for routing.

<?php

// Signature verification only; call this with the exact, unmodified HTTP body.
// Load the subscription's secret from secure server-side configuration.
function verifyServedHqWebhook(
    string $rawBody,
    string $timestamp,
    string $signatureV2,
    string $secret,
    ?int $now = null,
): array {
    if ($secret === '' || ! ctype_digit($timestamp)
        || abs(($now ?? time()) - (int) $timestamp) > 300
        || ! preg_match('/\A[a-f0-9]{64}\z/', $signatureV2)) {
        throw new RuntimeException('Invalid webhook authentication.');
    }

    $expected = hash_hmac('sha256', $timestamp.'.'.$rawBody, $secret);
    if (! hash_equals($expected, $signatureV2)) {
        throw new RuntimeException('Invalid webhook signature.');
    }

    $event = json_decode($rawBody, true, 512, JSON_THROW_ON_ERROR);
    if (! is_array($event) || ! is_string($event['id'] ?? null)
        || ! is_string($event['event'] ?? null) || ! is_array($event['data'] ?? null)) {
        throw new RuntimeException('Invalid webhook envelope.');
    }

    // Receiver must now persist using a unique (subscription, event ID) key.
    // A valid signature alone does not prevent duplicate processing.
    return $event;
}

Acknowledge, deduplicate & retry

  1. Verify the request, then durably store it using a unique key combining the subscription identity and event id.
  2. Return a 2xx response promptly after storing it, including for an already stored duplicate. Process the stored event asynchronously.
  3. Do not rely on delivery order. Reconcile the current record through the read API where needed.

Delivery has a 5-second connection timeout and a 10-second request timeout. The job permits up to three attempts total; normal queued retry delays are 10 seconds and then 60 seconds. Worker configuration can affect retry timing or reduce attempts. Non-2xx responses and network failures cause retries; redirects are rejected.

After retries are exhausted, delivery can be lost. Monitor the last delivery status and reconcile records through the read API; there is no public webhook delivery-history or replay endpoint. Disabled/deleted subscriptions, inactive businesses and disabled or expired Developer API access stop delivery.

Errors & retries

Errors can contain error and a machine-readable code. Validation errors use message and field-level errors.

StatusWhat to do
400Supply a valid Idempotency-Key for booking creation.
401Check the bearer token and its expiry/revocation.
403Check business access, required add-ons and token scopes.
404Check the numeric record ID belongs to the authenticated business.
409Recheck booking availability or resolve the idempotency conflict. Do not blindly retry a changed basket under the same key.
422Correct the fields identified in the validation response.
429Wait for Retry-After; back off repeated requests.

Lists return data and pagination meta: current page, last page and total. Use page and per_page (default 25, maximum 100).

Response & request schemas

Expand a schema to inspect its fields. Follow linked types for nested records.

Error
FieldTypeDetails
errorrequired string
code string Stable machine-readable error code when supplied.
ValidationError
FieldTypeDetails
messagerequired string
errorsrequired object
PaginationMeta
FieldTypeDetails
current_pagerequired integer Minimum: 1.
last_pagerequired integer Minimum: 1.
totalrequired integer Minimum: 0.
MenuResponse
FieldTypeDetails
datarequired array <MenuCategory>
MenuCategory
FieldTypeDetails
categoryrequired string
itemsrequired array <MenuItem>
MenuItem
FieldTypeDetails
idrequired integer Format: int64.
namerequired string
descriptionrequired string May be null.
price_pencerequired integer Minimum: 0.
is_availablerequired boolean
ServiceListResponse
FieldTypeDetails
datarequired array <BookableService>
BookableService
FieldTypeDetails
idrequired integer
menu string
category string
namerequired string
is_bookable boolean
durationrequired integer
requires_address boolean
is_enquiry_only boolean
price_pencerequired integer
option_groupsrequired array <OptionGroup>
OptionGroup
FieldTypeDetails
idrequired integer
namerequired string
description string May be null.
selection_typerequired string
min_selectionsrequired integer
max_selectionsrequired integer
is_requiredrequired boolean
optionsrequired array <ServiceOption>
ServiceOption
FieldTypeDetails
idrequired integer
namerequired string
description string May be null.
price_pencerequired integer
AvailabilityResponse
FieldTypeDetails
daterequired string Format: date.
duration_minutesrequired integer Total booking time for the requested party, including back-to-back runs for groups larger than the slot capacity.
slotsrequired array <string>
CreateReservationRequest
FieldTypeDetails
customer_namerequired string Max length: 150.
customer_emailrequired string Format: email. Max length: 255.
customer_phone string Max length: 30.
attendee_name string Max length: 150.
attendee_phone string Max length: 30.
service_name string Max length: 150.
service_address string Max length: 500.
party_sizerequired integer Minimum: 1.
reserved_date string Format: date.
reserved_time string Pattern: ^\\d{2}:\\d{2}$.
staff_member_id integer
notes string Max length: 500.
custom_field_values object
marketing_consent boolean
service_items array <ReservationServiceSelection> Max items: 20.
ReservationServiceSelection
FieldTypeDetails
menu_item_idrequired integer
selected_options array <object>
Item structure
{
    "type": "object",
    "required": [
        "group_id",
        "option_ids"
    ],
    "properties": {
        "group_id": {
            "type": "integer"
        },
        "option_ids": {
            "type": "array",
            "items": {
                "type": "integer"
            }
        }
    }
}
ReservationResponse
FieldTypeDetails
datarequired CreatedReservation
CreatedReservation
FieldTypeDetails
idrequired integer
statusrequired string
customer_namerequired string
customer_emailrequired string Format: email.
customer_phone string May be null.
service_name string May be null.
party_sizerequired integer
reserved_date string May be null. Format: date.
reserved_time string May be null.
total_duration_minutes integer May be null.
staff_member string May be null.
itemsrequired array <CreatedReservationItem>
created_atrequired string Format: date-time.
CreatedReservationItem
FieldTypeDetails
menu_item_idrequired integer May be null.
service_namerequired string
duration_minutesrequired integer Length of one run of this service.
price_pencerequired integer Line total (unit_price_pence x quantity).
quantityrequired integer People charged for this line (added in 1.1.0). Always 1 for restaurant bookings.
unit_price_pencerequired integer Price for one person including selected options (added in 1.1.0).
selected_options array <object> May be null.
PaymentRequiredResponse
FieldTypeDetails
statusrequired string Values: payment_required.
deposit_pencerequired integer
checkout_urlrequired string Format: uri.
OrderResponse
FieldTypeDetails
datarequired Order
OrderListResponse
FieldTypeDetails
datarequired array <Order>
metarequired PaginationMeta
Order
FieldTypeDetails
idrequired integer Format: int64.
statusrequired string
order_typerequired string
payment_methodrequired string
customer_namerequired string May be null.
customer_emailrequired string May be null. Format: email.
customer_phonerequired string May be null.
customer_addressrequired object May be null.
special_requestsrequired string May be null.
subtotal_pencerequired integer
delivery_fee_pencerequired integer
discount_pencerequired integer
total_pencerequired integer
refunded_pencerequired integer
itemsrequired array <OrderItem>
created_atrequired string Format: date-time.
OrderItem
FieldTypeDetails
namerequired string
quantityrequired number
price_pencerequired integer
total_pencerequired integer
ReservationListResponse
FieldTypeDetails
datarequired array <Reservation>
metarequired PaginationMeta
Reservation
FieldTypeDetails
idrequired integer Format: int64.
statusrequired string
customer_namerequired string May be null.
customer_emailrequired string May be null. Format: email.
customer_phonerequired string May be null.
service_namerequired string
party_sizerequired integer
total_duration_minutesrequired integer
reserved_daterequired string May be null. Format: date.
reserved_timerequired string May be null.
is_enquiry_onlyrequired boolean
attendee_namerequired string May be null.
attendee_phonerequired string May be null.
staff_memberrequired string May be null.
notesrequired string May be null.
created_atrequired string Format: date-time.

What you can build today

Connect a booking agent to services and availability, submit reservation requests, or build a dashboard/export that reads your menu, orders and reservations.

Current API boundaries

Order creation, menu or stock updates, cancellation/rescheduling, customer mutations and refunds are not exposed as API operations. The menu endpoint reports the stored availability flag, not full stock levels or effective daily-limit availability.

Outbound webhooks can be configured in the business admin. Webhook management is not an API operation in this version.

Need help with an integration? Talk to Served HQ →