API reference

Every endpoint of version 1, with its scope, parameters and fields.

Updated 2026-10-28

Base address: https://linesteward.com. Every request needs an API key (authentication). The OpenAPI 3.1 file: /v1/openapi.json.

Businesses, facts and documents

GET/v1/businesses

List businesses. Every business in the key's account, oldest first.

Scope: businesses:read

Answer: 200, BusinessList

Each item in data: Business.

POST/v1/businesses

Add a business. Add a business (a location with its own receptionist line) to the key's account. It shares the account's plan and minutes, so it needs a plan with room for another location (Enterprise). Sign-ups for a new account happen in the app.

Scope: businesses:write

Parameters

NameInTypeAbout
Idempotency-KeyheaderstringAny unique string (a UUID). A retry with the same key and body gets the first answer for 24 hours instead of doing it twice.

Body (JSON)

FieldTypeAbout
name requiredstring
business_type requiredone of salon, restaurant, garage, clinic, trades, estate_agent, other
websitestring (or null)
timezonestring
json{
  "business_type": "salon",
  "name": "Kettlewell Hair, Ilkley",
  "website": "https://kettlewellhair.example"
}

Answer: 201, Business

GET/v1/businesses/{business_id}

Get a business. One business: details, opening hours, the owner's texts, and the receptionist's name and greeting.

Scope: businesses:read

Parameters

NameInTypeAbout
business_id requiredpathstring

Answer: 200, Business

PATCH/v1/businesses/{business_id}

Update a business. Change only the fields you send. The receptionist uses the change from its next call.

Scope: businesses:write

Parameters

NameInTypeAbout
business_id requiredpathstring

Body (JSON)

FieldTypeAbout
namestring (or null)
timezonestring (or null)
addressstring (or null)
phonestring (or null)
websitestring (or null)
hoursobject (or null)Local opening times per day (mon to sun); a missing or empty day is closed.
closureslist of string (or null)Local dates closed all day, YYYY-MM-DD.
aboutstring (or null)About your business, in your words.
receptionist_rolestring (or null)What the receptionist should do for callers.
greetingstring (or null)The receptionist's first words. It always says it is an AI first; this follows.
agent_namestring (or null)
json{
  "greeting": "Hello, you're through to Kettlewell Hair. How can I help?",
  "hours": {
    "mon": [
      [
        "09:00",
        "17:30"
      ]
    ],
    "sat": [
      [
        "10:00",
        "14:00"
      ]
    ],
    "tue": [
      [
        "09:00",
        "17:30"
      ]
    ]
  }
}

Answer: 200, Business

PUT/v1/businesses/{business_id}/knowledge

Replace the facts. Replace one set of facts (services, prices, answers) the receptionist uses on calls. manual is the set typed in the app; website the set read from the website. The other set stays.

Scope: knowledge:write

Parameters

NameInTypeAbout
business_id requiredpathstring

Body (JSON)

FieldTypeAbout
facts requiredlist of Fact
sourceone of manual, websiteWhich set of facts to replace: manual (the ones typed in the app) or website (the ones read from the website). The other set is kept.
json{
  "facts": [
    {
      "duration_minutes": 60,
      "kind": "service",
      "price": 48,
      "title": "Women's cut and finish"
    },
    {
      "body": "Yes, free parking behind the salon.",
      "kind": "faq",
      "title": "Is there parking?"
    }
  ]
}

Answer: 200, Saved

POST/v1/businesses/{business_id}/documents

Upload a document. A PDF, Word (.docx), text, Markdown or CSV file the receptionist answers callers from. Send the file as the body and its name as ?name=. It is read in the background (status processing, then ready or failed; see it in the app). Only its text is kept; the file is deleted once read. The same limits as the app apply.

Scope: knowledge:write

Parameters

NameInTypeAbout
business_id requiredpathstring
namequerystringThe file's name, like price-list.pdf.
Idempotency-KeyheaderstringAny unique string (a UUID). A retry with the same key and body gets the first answer for 24 hours instead of doing it twice.

Body: The file itself, as the body (not a form).

Answer: 202, Document

Calls

GET/v1/calls

List calls. Calls, newest first: time, length, outcome, summary and the caller's number (callers' personal data). The transcript is on GET /v1/calls/{call_id}.

Scope: calls:read

Parameters

NameInTypeAbout
business_idquerystring (or null)Only this business (its id).
sincequerystring (or null)Only from this time on (ISO 8601).
untilquerystring (or null)Only before this time (ISO 8601).
outcomequeryone of booked, changed, cancelled, message, info, transferred, abandoned, failed (or null)
cursorquerystring (or null)next_cursor from the page before.
limitqueryintegerUp to 100; 25 if not given.

Answer: 200, CallPage

Each item in data: Call.

GET/v1/calls/{call_id}

Get a call. One call. Add ?include=transcript for what was said: it holds callers' personal data, so ask for it only when you need it and keep it no longer than your own retention time.

Scope: calls:read

Parameters

NameInTypeAbout
call_id requiredpathstring
includequerytranscript (or null)

Answer: 200, CallDetail

Messages

GET/v1/messages

List messages. Messages the receptionist took, newest first.

Scope: messages:read

Parameters

NameInTypeAbout
business_idquerystring (or null)Only this business (its id).
statusqueryone of open, done, all
urgentqueryboolean (or null)Only urgent ones.
sincequerystring (or null)Only from this time on (ISO 8601).
untilquerystring (or null)Only before this time (ISO 8601).
cursorquerystring (or null)next_cursor from the page before.
limitqueryintegerUp to 100; 25 if not given.

Answer: 200, MessagePage

Each item in data: Message.

Bookings

GET/v1/bookings

List bookings. Bookings, newest made first. Filter by when they start with starts_after / starts_before.

Scope: bookings:read

Parameters

NameInTypeAbout
business_idquerystring (or null)Only this business (its id).
statusqueryone of confirmed, cancelled, completed, no_show (or null)
starts_afterquerystring (or null)
starts_beforequerystring (or null)
cursorquerystring (or null)next_cursor from the page before.
limitqueryintegerUp to 100; 25 if not given.

Answer: 200, BookingPage

Each item in data: Booking.

POST/v1/bookings

Make a booking. Book a time with the same rules the receptionist uses on calls: the skill must be on, the time must be open, on the booking grid, after the notice and within the days ahead, the service must be one the business lists, and there must be room. No text is sent to the customer. Not for businesses that book into a connected booking system, or trades job visits.

Scope: bookings:write

Parameters

NameInTypeAbout
Idempotency-KeyheaderstringAny unique string (a UUID). A retry with the same key and body gets the first answer for 24 hours instead of doing it twice.

Body (JSON)

FieldTypeAbout
business_id requiredstring
kindone of appointment, table
starts_at requiredstring (date-time)With its UTC offset, like 2026-11-04T10:30:00+00:00. It must be a free time the receptionist would offer: open, on the booking grid, after the notice.
servicestring (or null)A bookable service's name, when the business lists services (appointments).
party_sizeinteger (or null)Tables: how many people.
customer_name requiredstring
customer_phonestring (or null)
notesstring (or null)
json{
  "business_id": "3f0c6a8e-1b2d-4c5e-8f90-a1b2c3d4e5f6",
  "customer_name": "Sam Patel",
  "customer_phone": "+447700900123",
  "kind": "appointment",
  "service": "Women's cut and finish",
  "starts_at": "2026-11-04T10:30:00+00:00"
}

Answer: 201, Booking

GET/v1/bookings/{booking_id}

Get a booking. One booking.

Scope: bookings:read

Parameters

NameInTypeAbout
booking_id requiredpathstring

Answer: 200, Booking

DELETE/v1/bookings/{booking_id}

Cancel a booking. Cancel a confirmed booking that hasn't started, with at least the business's cancellation notice. No text is sent to the customer. Cancelling twice is fine.

Scope: bookings:write

Parameters

NameInTypeAbout
booking_id requiredpathstring

Answer: 200, Booking

Webhooks

GET/v1/webhooks

List webhooks. Each business has at most one webhook address: the same one Settings, "Send to other apps" sets in the app. The signing secret is never shown again.

Scope: webhooks:write

Answer: 200, WebhookList

Each item in data: Webhook.

POST/v1/webhooks

Set a webhook. Set the business's webhook address and events. It replaces the one set before (in the app too), and makes a new signing secret, shown once in the answer.

Scope: webhooks:write

Parameters

NameInTypeAbout
Idempotency-KeyheaderstringAny unique string (a UUID). A retry with the same key and body gets the first answer for 24 hours instead of doing it twice.

Body (JSON)

FieldTypeAbout
business_id requiredstring
url requiredstring
eventslist of one of call.completed, message.created, booking.created, booking.cancelled (or null)Default: all four events.
json{
  "business_id": "3f0c6a8e-1b2d-4c5e-8f90-a1b2c3d4e5f6",
  "events": [
    "call.completed",
    "booking.created"
  ],
  "url": "https://example.com/hooks/receptionist"
}

Answer: 201, WebhookCreated

DELETE/v1/webhooks/{webhook_id}

Delete a webhook. Stop sending events to it. Events not sent yet are dropped.

Scope: webhooks:write

Parameters

NameInTypeAbout
webhook_id requiredpathstring

Answer: 200, Deleted

Objects

Business

FieldTypeAbout
id requiredstring
name requiredstring
business_type requiredstring
timezone requiredstring
addressstring (or null)
phonestring (or null)
websitestring (or null)
hoursobject
closureslist of any
aboutstring (or null)
receptionist_rolestring (or null)
greetingstring (or null)
agent_namestring (or null)
created_atstring (date-time) (or null)

Call

FieldTypeAbout
id requiredstring
business_id requiredstring
started_at requiredstring (date-time)
ended_atstring (date-time) (or null)
secondsinteger
outcomestring (or null)
summarystring (or null)
caller_phonestring (or null)
languagestring (or null)

CallDetail

FieldTypeAbout
id requiredstring
business_id requiredstring
started_at requiredstring (date-time)
ended_atstring (date-time) (or null)
secondsinteger
outcomestring (or null)
summarystring (or null)
caller_phonestring (or null)
languagestring (or null)
transcriptlist of any (or null)Only with ?include=transcript. Callers' personal data.

Message

FieldTypeAbout
id requiredstring
business_id requiredstring
call_idstring (or null)
kind requiredstring
caller_name requiredstring
caller_phonestring (or null)
body requiredstring
urgentboolean
callback_timestring (or null)
addressstring (or null)
status requiredstring
created_at requiredstring (date-time)

Booking

FieldTypeAbout
id requiredstring
business_id requiredstring
call_idstring (or null)
kind requiredstring
ref requiredstring
status requiredstring
servicestring (or null)
starts_at requiredstring (date-time)
ends_at requiredstring (date-time)
party_sizeinteger
customer_name requiredstring
customer_phonestring (or null)
notesstring (or null)
source requiredstring
created_atstring (date-time) (or null)
cancelled_atstring (date-time) (or null)

Webhook

FieldTypeAbout
id requiredstring
business_id requiredstring
url requiredstring
events requiredlist of string
enabledboolean
last_statusinteger (or null)
last_errorstring (or null)
created_atstring (date-time) (or null)

WebhookCreated

FieldTypeAbout
id requiredstring
business_id requiredstring
url requiredstring
events requiredlist of string
enabledboolean
last_statusinteger (or null)
last_errorstring (or null)
created_atstring (date-time) (or null)
signing_secret requiredstringShown once. Use it to check the X-Receptionist-Signature header.

Document

FieldTypeAbout
id requiredstring
name requiredstring
kind requiredstring
bytes requiredinteger
status requiredstring

ErrorBody

FieldTypeAbout
error requiredErrorDetail

Get your API key

Sign in, open Settings, then Developers, and make a key with the scopes you need.