Developers
Contents
On this page

Using the API

Requests and responses

How every request and response is shaped.

JSON in, JSON out#

  • Send bodies as JSON with Content-Type: application/json, at most 1 MB. A GET takes its filters in the query string and has no body. A write — POST, PUT, PATCH — takes every field in its body and no query string at all: one is refused with a 400 BAD_REQUEST.
  • Every answer is JSON. A successful one is 200; a refused one has the error body.
  • A list comes wrapped — { "data": [ … ] } — so it can grow a field such as nextCursor without breaking anybody.
  • Every field a resource has is always in the answer. When it has no value it is null, never missing: a waiting visit's deskId is null, not absent.
  • Ignore fields you do not know. Within v1 we add fields; a client that refuses an answer with one more field than it expected will break on a day we announced as safe.
  • PUT replaces: send every setting, as PUT /v1/lines describes. PATCH changes only the fields you send. A field you send as null clears it, where the field allows null.

Ids#

Every id is a short prefix that says what it is, a hyphen, and a UUID — for example line-0193f2a1-7c4e-7a10-9b2e-000000000001. Treat ids as opaque strings up to 64 characters; compare them exactly, and never build one.

Id prefixes
PrefixNames
bus- A business
line- A line
svc- A service, or a heading on the menu
sta- A desk
job- A visit
jny- A journey — the visits one person made in one go, across lines
evt- A webhook event
whd- One delivery of an event to one endpoint

A visit's token — the number on the customer's screen and the desk's board — is for people, not for code. It is unique on its line for its day and repeats on other days. Find a visit by its id.

Timestamps and time zones#

Every moment is an ISO 8601 string in UTC, to the millisecond: 2026-10-30T04:31:00.000Z. When you send one (a break's backAt, a sync's updatedSince) you may give any offset — +05:30 is fine — and it is read as that moment.

Show times to people in the business's own zone, not your server's: GET /v1/business answers its timeZone (an IANA name such as Asia/Kolkata) and its clockFormat, 12h or 24h, which is how its staff expect to read a time.

A business's day#

"Today" is the business's today, in its time zone — never UTC's and never your server's. A clinic in Kolkata that opens at 7 am is open on a date for which UTC still says yesterday.

  • GET /v1/business answers today as YYYY-MM-DD.
  • from and to on GET /v1/visits are the business's dates, and both are included: from=to=today is one whole day.
  • A visit belongs to the day of its booking slot when it has one, and otherwise to the day it was added.
GET /v1/business
{
  "id": "bus-0193f2a1-7c4e-7a10-9b2e-000000000001",
  "name": "Sunrise Clinic",
  "slug": "sunrise-clinic",
  "category": "healthcare",
  "timeZone": "Asia/Kolkata",
  "today": "2026-10-30",
  "clockFormat": "12h"
}

Pagination with cursors#

GET /v1/visits answers a page at a time, newest first: by the booking slot, or for a walk-in by when it was added. Ask for up to 100 with limit (50 if you do not say). Each page carries nextCursor; send it back as cursor for the next page. On the last page it is null.

The first page

curl

curl "https://business.linemeup.in/api/v1/visits?lineId=line-0193f2a1-7c4e-7a10-9b2e-000000000001&from=2026-10-30&to=2026-10-30&limit=2" \
  -H "Authorization: Bearer $LINEMEUP_API_KEY"

Node

const res = await fetch("https://business.linemeup.in/api/v1/visits?lineId=line-0193f2a1-7c4e-7a10-9b2e-000000000001&from=2026-10-30&to=2026-10-30&limit=2", {
  headers: {
    Authorization: `Bearer ${process.env.LINEMEUP_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Line Me Up answered ${res.status}`);
const answer = await res.json();

Python

import os
import requests

res = requests.get(
    "https://business.linemeup.in/api/v1/visits?lineId=line-0193f2a1-7c4e-7a10-9b2e-000000000001&from=2026-10-30&to=2026-10-30&limit=2",
    headers={
        "Authorization": f"Bearer {os.environ['LINEMEUP_API_KEY']}",
    },
    timeout=10,
)
res.raise_for_status()
answer = res.json()

PHP

<?php
$ch = curl_init("https://business.linemeup.in/api/v1/visits?lineId=line-0193f2a1-7c4e-7a10-9b2e-000000000001&from=2026-10-30&to=2026-10-30&limit=2");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("LINEMEUP_API_KEY"),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
]);
$answer = json_decode(curl_exec($ch), true);
Response (200)
{
  "data": [
    {
      "id": "job-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "journeyId": "jny-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "token": "GEN-20261030-014",
      "lineId": "line-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "status": "queued",
      "bookingType": "walk_in",
      "priority": false,
      "note": "First visit",
      "customer": {
        "name": "Asha Rao",
        "phone": "+919000000001"
      },
      "services": [
        {
          "id": "svc-0193f2a1-7c4e-7a10-9b2e-000000000002",
          "name": "General consultation"
        }
      ],
      "deskId": null,
      "position": 3,
      "slotAt": null,
      "createdAt": "2026-10-30T04:12:00.000Z",
      "calledAt": null,
      "startedAt": null,
      "endedAt": null,
      "updatedAt": "2026-10-30T04:12:00.000Z"
    },
    {
      "id": "job-0193f2a1-7c4e-7a10-9b2e-000000000004",
      "journeyId": "jny-0193f2a1-7c4e-7a10-9b2e-000000000004",
      "token": "GEN-20261030-009",
      "lineId": "line-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "status": "completed",
      "bookingType": "walk_in",
      "priority": false,
      "note": null,
      "customer": {
        "name": null,
        "phone": null
      },
      "services": [
        {
          "id": "svc-0193f2a1-7c4e-7a10-9b2e-000000000002",
          "name": "General consultation"
        }
      ],
      "deskId": "sta-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "position": null,
      "slotAt": null,
      "createdAt": "2026-10-30T03:40:00.000Z",
      "calledAt": "2026-10-30T03:58:00.000Z",
      "startedAt": "2026-10-30T03:59:00.000Z",
      "endedAt": "2026-10-30T04:10:00.000Z",
      "updatedAt": "2026-10-30T04:10:00.000Z"
    }
  ],
  "nextCursor": "MjAyNi0xMC0yNVQwNDoxMDowMC4wMDAwMDBafGpvYi0wMDA0"
}
The next page

curl

curl "https://business.linemeup.in/api/v1/visits?cursor=MjAyNi0xMC0yNVQwNDoxMDowMC4wMDAwMDBafGpvYi0wMDA0&limit=2" \
  -H "Authorization: Bearer $LINEMEUP_API_KEY"

Node

const res = await fetch("https://business.linemeup.in/api/v1/visits?cursor=MjAyNi0xMC0yNVQwNDoxMDowMC4wMDAwMDBafGpvYi0wMDA0&limit=2", {
  headers: {
    Authorization: `Bearer ${process.env.LINEMEUP_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Line Me Up answered ${res.status}`);
const answer = await res.json();

Python

import os
import requests

res = requests.get(
    "https://business.linemeup.in/api/v1/visits?cursor=MjAyNi0xMC0yNVQwNDoxMDowMC4wMDAwMDBafGpvYi0wMDA0&limit=2",
    headers={
        "Authorization": f"Bearer {os.environ['LINEMEUP_API_KEY']}",
    },
    timeout=10,
)
res.raise_for_status()
answer = res.json()

PHP

<?php
$ch = curl_init("https://business.linemeup.in/api/v1/visits?cursor=MjAyNi0xMC0yNVQwNDoxMDowMC4wMDAwMDBafGpvYi0wMDA0&limit=2");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("LINEMEUP_API_KEY"),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
]);
$answer = json_decode(curl_exec($ch), true);
Response (200) — the last page
{
  "data": [],
  "nextCursor": null
}

A cursor is opaque. Send it back exactly as it came, with the same filters; do not decode, build or store it for long. A cursor we cannot read is a 422. A visit added while you page is newer than your first page, so it is not on a later one; start again from the first page, or use updatedSince, to pick it up.

Reading every page
// Every visit of the business's today, page by page.
// get() sends the key and returns the JSON — the Guides have a complete one.
const { today } = await get("/business");
const visits = [];
let cursor = null;
do {
  const query = new URLSearchParams({ from: today, to: today, limit: "100" });
  if (cursor) query.set("cursor", cursor);
  const page = await get(`/visits?${query}`);
  visits.push(...page.data);
  cursor = page.nextCursor;
} while (cursor !== null);

Filtering#

Every filter on GET /v1/visits is optional, and they combine with AND.

Visit filters
ParameterKeeps visits
status In any of these statuses: booked, queued, called, in_progress, completed, cancelled, no_show.
lineId On any of these lines. A line the key may not see matches nothing.
from, to On these business days, both included, YYYY-MM-DD.
updatedSince Changed at or after this moment — the filter for a sync.
limit, cursor The page size, 1 to 100, and the page.

A filter that takes several values takes them repeated, or comma-separated:

GET /v1/visits?status=queued&status=called
GET /v1/visits?status=queued,called

For a sync, remember the time you started your last read and pass it as updatedSince next time — not the time you finished, which would skip whatever changed while you read.

What changed since 9:30 am in Kolkata

curl

curl "https://business.linemeup.in/api/v1/visits?updatedSince=2026-10-30T04%3A00%3A00.000Z&limit=100" \
  -H "Authorization: Bearer $LINEMEUP_API_KEY"

Node

const res = await fetch("https://business.linemeup.in/api/v1/visits?updatedSince=2026-10-30T04%3A00%3A00.000Z&limit=100", {
  headers: {
    Authorization: `Bearer ${process.env.LINEMEUP_API_KEY}`,
  },
});
if (!res.ok) throw new Error(`Line Me Up answered ${res.status}`);
const answer = await res.json();

Python

import os
import requests

res = requests.get(
    "https://business.linemeup.in/api/v1/visits?updatedSince=2026-10-30T04%3A00%3A00.000Z&limit=100",
    headers={
        "Authorization": f"Bearer {os.environ['LINEMEUP_API_KEY']}",
    },
    timeout=10,
)
res.raise_for_status()
answer = res.json()

PHP

<?php
$ch = curl_init("https://business.linemeup.in/api/v1/visits?updatedSince=2026-10-30T04%3A00%3A00.000Z&limit=100");
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => [
        "Authorization: Bearer " . getenv("LINEMEUP_API_KEY"),
    ],
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 10,
]);
$answer = json_decode(curl_exec($ch), true);
Response (200)
{
  "data": [
    {
      "id": "job-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "journeyId": "jny-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "token": "GEN-20261030-014",
      "lineId": "line-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "status": "completed",
      "bookingType": "walk_in",
      "priority": false,
      "note": "First visit",
      "customer": {
        "name": "Asha Rao",
        "phone": "+919000000001"
      },
      "services": [
        {
          "id": "svc-0193f2a1-7c4e-7a10-9b2e-000000000002",
          "name": "General consultation"
        }
      ],
      "deskId": "sta-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "position": null,
      "slotAt": null,
      "createdAt": "2026-10-30T04:12:00.000Z",
      "calledAt": "2026-10-30T04:31:00.000Z",
      "startedAt": "2026-10-30T04:32:00.000Z",
      "endedAt": "2026-10-30T04:47:00.000Z",
      "updatedAt": "2026-10-30T04:47:00.000Z"
    },
    {
      "id": "job-0193f2a1-7c4e-7a10-9b2e-000000000004",
      "journeyId": "jny-0193f2a1-7c4e-7a10-9b2e-000000000004",
      "token": "GEN-20261030-009",
      "lineId": "line-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "status": "completed",
      "bookingType": "walk_in",
      "priority": false,
      "note": null,
      "customer": {
        "name": null,
        "phone": null
      },
      "services": [
        {
          "id": "svc-0193f2a1-7c4e-7a10-9b2e-000000000002",
          "name": "General consultation"
        }
      ],
      "deskId": "sta-0193f2a1-7c4e-7a10-9b2e-000000000001",
      "position": null,
      "slotAt": null,
      "createdAt": "2026-10-30T03:40:00.000Z",
      "calledAt": "2026-10-30T03:58:00.000Z",
      "startedAt": "2026-10-30T03:59:00.000Z",
      "endedAt": "2026-10-30T04:10:00.000Z",
      "updatedAt": "2026-10-30T04:10:00.000Z"
    }
  ],
  "nextCursor": null
}