{"openapi":"3.1.0","info":{"title":"Tellfox API","version":"1","description":"Connect Tellfox to your other software. Keys are made on Settings → API in the Tellfox owner pages. Docs: https://tellfox.app/developers/"},"servers":[{"url":"https://api.tellfox.app"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Your secret key (tfx_live_… or tfx_test_…)."}}},"paths":{"/v1/business":{"get":{"operationId":"business.get","summary":"The business and the key","description":"The business this key belongs to, its branches, and what the key may do. A good first call to check a key works.\n\nAny key.","tags":["Business"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^biz_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"biz_…\")."},"name":{"type":"string"},"name_en":{"type":["string","null"]},"timezone":{"type":"string","description":"Times are stored in UTC; this is the zone the business shows them in."},"language":{"type":"string","enum":["th","en"]},"currency":{"type":"string","const":"THB","description":"Money is in satang (1 baht = 100 satang), whole numbers."},"mode":{"type":"string","enum":["live","test"],"description":"`test`: a test copy of the business, where nothing is ever sent to anyone."},"key":{"type":"object","properties":{"name":{"type":"string"},"system":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"branch_ids":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"The branches the key is limited to, or null for all."}},"required":["name","system","scopes","branch_ids"],"additionalProperties":false},"branches":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^loc_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"loc_…\")."},"name":{"type":"string"},"primary":{"type":"boolean","description":"The first branch."},"status":{"type":"string","enum":["active","paused"],"description":"A paused branch (free account) takes no new bookings."},"address":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["id","name","primary","status","address","phone"],"additionalProperties":false}}},"required":["id","name","name_en","timezone","language","currency","mode","key","branches"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/branches":{"get":{"operationId":"branches.list","summary":"Branches","description":"The open and paused branches (the ones the key may use).\n\nAny key.","tags":["Business"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^loc_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"loc_…\")."},"name":{"type":"string"},"primary":{"type":"boolean","description":"The first branch."},"status":{"type":"string","enum":["active","paused"],"description":"A paused branch (free account) takes no new bookings."},"address":{"type":["string","null"]},"phone":{"type":["string","null"]}},"required":["id","name","primary","status","address","phone"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/services":{"get":{"operationId":"services.list","summary":"Services and classes","description":"The active services and classes, in the order the business shows them.\n\nAny key.","tags":["Business"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^svc_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"svc_…\")."},"name":{"type":"string"},"name_en":{"type":["string","null"]},"kind":{"type":"string","enum":["appointment","class"],"description":"`class`: booked as a place in a scheduled session."},"unit":{"type":"string","enum":["time","day"],"description":"`day`: a stay booked by the night."},"duration_minutes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"price":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Satang; null when the service has no price."},"branch_ids":{"type":"array","items":{"type":"string"},"description":"The branches that offer it."},"bookable_online":{"type":"boolean"}},"required":["id","name","name_en","kind","unit","duration_minutes","price","branch_ids","bookable_online"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/team":{"get":{"operationId":"team.list","summary":"The team","description":"The active team members: names and branches only, never their contact details.\n\nAny key.","tags":["Business"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^mem_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"mem_…\")."},"name":{"type":"string"},"name_en":{"type":["string","null"]},"bookable":{"type":"boolean","description":"Customers can book this person."},"branch_ids":{"type":"array","items":{"type":"string"}}},"required":["id","name","name_en","bookable","branch_ids"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/tags":{"get":{"operationId":"tags.list","summary":"Customer tags","description":"Scope: `customers:read`.","tags":["Customers"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers":{"get":{"operationId":"customers.list","summary":"List or find customers","description":"Oldest change first, so a sync reads every change: keep the last `updated_at` you saw and send it as `updated_since` next time. Find one customer with `phone`, `email` or `external_id`. Customers belong to the whole business (every branch).\n\nScope: `customers:read`.","tags":["Customers"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to answer, 1 to 200 (default 50).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","default":50,"description":"How many to answer, 1 to 200 (default 50).","type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before, to read the next page.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before, to read the next page.","type":"string","maxLength":400}},{"name":"updated_since","in":"query","required":false,"description":"Only what changed at or after this time (UTC, as `updated_at` gives it). Send a minute before the last `updated_at` you saw.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Only what changed at or after this time (UTC, as `updated_at` gives it). Send a minute before the last `updated_at` you saw.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"q","in":"query","required":false,"description":"Part of a name, phone number or email.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Part of a name, phone number or email.","type":"string","maxLength":80}},{"name":"phone","in":"query","required":false,"description":"An exact phone number (any format; Thai numbers may start with 0).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"An exact phone number (any format; Thai numbers may start with 0).","type":"string","maxLength":30}},{"name":"email","in":"query","required":false,"description":"An exact email address.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"An exact email address.","type":"string","maxLength":254}},{"name":"external_id","in":"query","required":false,"description":"This key's system's own ID.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"This key's system's own ID.","type":"string","maxLength":100}},{"name":"tag","in":"query","required":false,"description":"A tag ID.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"A tag ID.","type":"string","maxLength":64}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"name":{"type":"string"},"phones":{"type":"array","items":{"type":"string"},"description":"E.164 (\"+66812345678\")."},"emails":{"type":"array","items":{"type":"string"}},"on_line":{"type":"boolean","description":"The customer is reached on LINE (the LINE ID itself is never given)."},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD.","type":["string","null"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"consent":{"type":"object","properties":{"line":{"type":"boolean"},"email":{"type":"boolean"}},"required":["line","email"],"additionalProperties":false,"description":"Agreed to receive offers on that channel (PDPA). Service messages need none."},"external_id":{"description":"This key's system's own ID for the customer.","type":["string","null"]},"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Completed bookings and class places, and served queue tickets."},"last_visit_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"next_booking_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"anonymised":{"type":"boolean","description":"Erased on request (PDPA): the name is a placeholder and contact details are gone."},"created_from":{"type":"string"},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change to the customer, their contact details, tags, consent or IDs (not their visit numbers, which follow the bookings). Use it as `updated_since`."}},"required":["id","name","phones","emails","on_line","language","birthday","tags","consent","external_id","visits","last_visit_at","next_booking_at","anonymised","created_from","created_at","updated_at"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}},"post":{"operationId":"customers.create","summary":"Add a customer (or find the one the business has)","description":"Finds the customer by your `external_id`, then the email, then the phone (a phone a customer proved on their own sign-in is never handed to a new one). Answers 201 with a new customer, 200 with the one found, who keeps their own details (a birthday is added only when they have none; your `external_id` is attached; add contact details with PATCH). Refused before anything is written when the found customer has another `external_id` from your system. Shows in the activity feed under the key's name.\n\nScope: `customers:write`.","tags":["Customers"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"name":{"type":"string"},"phones":{"type":"array","items":{"type":"string"},"description":"E.164 (\"+66812345678\")."},"emails":{"type":"array","items":{"type":"string"}},"on_line":{"type":"boolean","description":"The customer is reached on LINE (the LINE ID itself is never given)."},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD.","type":["string","null"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"consent":{"type":"object","properties":{"line":{"type":"boolean"},"email":{"type":"boolean"}},"required":["line","email"],"additionalProperties":false,"description":"Agreed to receive offers on that channel (PDPA). Service messages need none."},"external_id":{"description":"This key's system's own ID for the customer.","type":["string","null"]},"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Completed bookings and class places, and served queue tickets."},"last_visit_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"next_booking_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"anonymised":{"type":"boolean","description":"Erased on request (PDPA): the name is a placeholder and contact details are gone."},"created_from":{"type":"string"},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change to the customer, their contact details, tags, consent or IDs (not their visit numbers, which follow the bookings). Use it as `updated_since`."}},"required":["id","name","phones","emails","on_line","language","birthday","tags","consent","external_id","visits","last_visit_at","next_booking_at","anonymised","created_from","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"phone":{"anyOf":[{"type":"string","minLength":1,"maxLength":30,"description":"A phone number in any format; Thai numbers may start with 0 (\"081-234-5678\")."},{"type":"null"}]},"email":{"description":"An email address.","anyOf":[{"type":"string","minLength":3,"maxLength":254},{"type":"null"}]},"language":{"description":"The language messages go out in (default th).","type":"string","enum":["th","en"]},"birthday":{"anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"YYYY-MM-DD."},{"type":"null"}]},"external_id":{"anyOf":[{"type":"string","minLength":1,"maxLength":100,"description":"Your system's own ID for the customer (kept per key system name)."},{"type":"null"}]},"tags":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":30},"description":"Tag names; a new name makes the tag (at most 100 per business, 20 per customer)."}},"required":["name"]}}}}}},"/v1/customers/erased":{"get":{"operationId":"customers.erased","summary":"Customers erased on request","description":"Customers the business erased (PDPA) by deleting them, oldest first, kept 180 days: delete your copy. A customer with bookings is anonymised instead and stays in the list of customers with `anonymised: true`.\n\nScope: `customers:read`.","tags":["Customers"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to answer, 1 to 200 (default 50).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","default":50,"description":"How many to answer, 1 to 200 (default 50).","type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before, to read the next page.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before, to read the next page.","type":"string","maxLength":400}},{"name":"updated_since","in":"query","required":false,"description":"Only what changed at or after this time (UTC, as `updated_at` gives it). Send a minute before the last `updated_at` you saw.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Only what changed at or after this time (UTC, as `updated_at` gives it). Send a minute before the last `updated_at` you saw.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"erased_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."}},"required":["id","erased_at"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers/{customer_id}":{"get":{"operationId":"customers.get","summary":"A customer","description":"Scope: `customers:read`.","tags":["Customers"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"name":{"type":"string"},"phones":{"type":"array","items":{"type":"string"},"description":"E.164 (\"+66812345678\")."},"emails":{"type":"array","items":{"type":"string"}},"on_line":{"type":"boolean","description":"The customer is reached on LINE (the LINE ID itself is never given)."},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD.","type":["string","null"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"consent":{"type":"object","properties":{"line":{"type":"boolean"},"email":{"type":"boolean"}},"required":["line","email"],"additionalProperties":false,"description":"Agreed to receive offers on that channel (PDPA). Service messages need none."},"external_id":{"description":"This key's system's own ID for the customer.","type":["string","null"]},"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Completed bookings and class places, and served queue tickets."},"last_visit_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"next_booking_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"anonymised":{"type":"boolean","description":"Erased on request (PDPA): the name is a placeholder and contact details are gone."},"created_from":{"type":"string"},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change to the customer, their contact details, tags, consent or IDs (not their visit numbers, which follow the bookings). Use it as `updated_since`."}},"required":["id","name","phones","emails","on_line","language","birthday","tags","consent","external_id","visits","last_visit_at","next_booking_at","anonymised","created_from","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}},"patch":{"operationId":"customers.update","summary":"Change a customer","description":"Name, language, birthday, your `external_id`, and phones and emails to add or remove (at most 3 of each per customer).\n\nScope: `customers:write`.","tags":["Customers"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"name":{"type":"string"},"phones":{"type":"array","items":{"type":"string"},"description":"E.164 (\"+66812345678\")."},"emails":{"type":"array","items":{"type":"string"}},"on_line":{"type":"boolean","description":"The customer is reached on LINE (the LINE ID itself is never given)."},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD.","type":["string","null"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"consent":{"type":"object","properties":{"line":{"type":"boolean"},"email":{"type":"boolean"}},"required":["line","email"],"additionalProperties":false,"description":"Agreed to receive offers on that channel (PDPA). Service messages need none."},"external_id":{"description":"This key's system's own ID for the customer.","type":["string","null"]},"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Completed bookings and class places, and served queue tickets."},"last_visit_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"next_booking_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"anonymised":{"type":"boolean","description":"Erased on request (PDPA): the name is a placeholder and contact details are gone."},"created_from":{"type":"string"},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change to the customer, their contact details, tags, consent or IDs (not their visit numbers, which follow the bookings). Use it as `updated_since`."}},"required":["id","name","phones","emails","on_line","language","birthday","tags","consent","external_id","visits","last_visit_at","next_booking_at","anonymised","created_from","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD, or null to clear it.","anyOf":[{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"YYYY-MM-DD."},{"type":"null"}]},"external_id":{"description":"Your system's own ID, or null to remove it.","anyOf":[{"type":"string","minLength":1,"maxLength":100,"description":"Your system's own ID for the customer (kept per key system name)."},{"type":"null"}]},"add_phones":{"maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":30,"description":"A phone number in any format; Thai numbers may start with 0 (\"081-234-5678\")."}},"remove_phones":{"description":"Only numbers the customer did not prove themselves.","maxItems":3,"type":"array","items":{"type":"string","minLength":1,"maxLength":30,"description":"A phone number in any format; Thai numbers may start with 0 (\"081-234-5678\")."}},"add_emails":{"maxItems":3,"type":"array","items":{"type":"string","minLength":3,"maxLength":254}},"remove_emails":{"description":"Only addresses the customer did not prove themselves.","maxItems":3,"type":"array","items":{"type":"string","minLength":3,"maxLength":254}}}}}}}}},"/v1/customers/{customer_id}/tags":{"post":{"operationId":"customer_tags.add","summary":"Add tags","description":"Scope: `customers:write`.","tags":["Customers"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"name":{"type":"string"},"phones":{"type":"array","items":{"type":"string"},"description":"E.164 (\"+66812345678\")."},"emails":{"type":"array","items":{"type":"string"}},"on_line":{"type":"boolean","description":"The customer is reached on LINE (the LINE ID itself is never given)."},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD.","type":["string","null"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"consent":{"type":"object","properties":{"line":{"type":"boolean"},"email":{"type":"boolean"}},"required":["line","email"],"additionalProperties":false,"description":"Agreed to receive offers on that channel (PDPA). Service messages need none."},"external_id":{"description":"This key's system's own ID for the customer.","type":["string","null"]},"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Completed bookings and class places, and served queue tickets."},"last_visit_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"next_booking_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"anonymised":{"type":"boolean","description":"Erased on request (PDPA): the name is a placeholder and contact details are gone."},"created_from":{"type":"string"},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change to the customer, their contact details, tags, consent or IDs (not their visit numbers, which follow the bookings). Use it as `updated_since`."}},"required":["id","name","phones","emails","on_line","language","birthday","tags","consent","external_id","visits","last_visit_at","next_booking_at","anonymised","created_from","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tags":{"minItems":1,"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":30},"description":"Tag names; a new name makes the tag (at most 100 per business, 20 per customer)."}},"required":["tags"]}}}}}},"/v1/customers/{customer_id}/tags/{tag_id}":{"delete":{"operationId":"customer_tags.remove","summary":"Take a tag off","description":"The tag stays in the business’s list.\n\nScope: `customers:write`.","tags":["Customers"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"tag_id","in":"path","required":true,"description":"A Tellfox ID (\"tag_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"name":{"type":"string"},"phones":{"type":"array","items":{"type":"string"},"description":"E.164 (\"+66812345678\")."},"emails":{"type":"array","items":{"type":"string"}},"on_line":{"type":"boolean","description":"The customer is reached on LINE (the LINE ID itself is never given)."},"language":{"type":"string","enum":["th","en"]},"birthday":{"description":"YYYY-MM-DD.","type":["string","null"]},"tags":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^tag_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"tag_…\")."},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}},"consent":{"type":"object","properties":{"line":{"type":"boolean"},"email":{"type":"boolean"}},"required":["line","email"],"additionalProperties":false,"description":"Agreed to receive offers on that channel (PDPA). Service messages need none."},"external_id":{"description":"This key's system's own ID for the customer.","type":["string","null"]},"visits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Completed bookings and class places, and served queue tickets."},"last_visit_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"next_booking_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"anonymised":{"type":"boolean","description":"Erased on request (PDPA): the name is a placeholder and contact details are gone."},"created_from":{"type":"string"},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change to the customer, their contact details, tags, consent or IDs (not their visit numbers, which follow the bookings). Use it as `updated_since`."}},"required":["id","name","phones","emails","on_line","language","birthday","tags","consent","external_id","visits","last_visit_at","next_booking_at","anonymised","created_from","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers/{customer_id}/notes":{"post":{"operationId":"notes.create","summary":"Add a note","description":"The team sees it on the customer’s page, under the key’s name.\n\nScope: `customers:write`.","tags":["Customers"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"body":{"type":"string"},"booking_id":{"type":["string","null"]},"author":{"type":["string","null"]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."}},"required":["id","body","booking_id","author","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"body":{"type":"string","minLength":1,"maxLength":2000},"booking_id":{"description":"One of the customer’s bookings it is about.","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]}},"required":["body"]}}}}},"get":{"operationId":"notes.list","summary":"A customer's notes","description":"Newest first.\n\nScope: `customers:read`.","tags":["Customers"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"limit","in":"query","required":false,"description":"How many to answer, 1 to 200 (default 50).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","default":50,"description":"How many to answer, 1 to 200 (default 50).","type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before, to read the next page.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before, to read the next page.","type":"string","maxLength":400}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"body":{"type":"string"},"booking_id":{"type":["string","null"]},"author":{"type":["string","null"]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."}},"required":["id","body","booking_id","author","created_at","updated_at"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/bookings":{"get":{"operationId":"bookings.list","summary":"List bookings and class places","description":"By start time between `from` and `to` (at most 93 days), or, with `updated_since`, oldest change first for a sync. A key limited to some branches sees only theirs.\n\nScope: `bookings:read`.","tags":["Bookings"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to answer, 1 to 200 (default 50).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","default":50,"description":"How many to answer, 1 to 200 (default 50).","type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before, to read the next page.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before, to read the next page.","type":"string","maxLength":400}},{"name":"from","in":"query","required":false,"description":"Starts at or after (UTC). Default: now.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Starts at or after (UTC). Default: now.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"to","in":"query","required":false,"description":"Starts before (UTC). Default: 31 days after `from`.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Starts before (UTC). Default: 31 days after `from`.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"updated_since","in":"query","required":false,"description":"Only what changed at or after this time (UTC, as `updated_at` gives it). Send a minute before the last `updated_at` you saw.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Only what changed at or after this time (UTC, as `updated_at` gives it). Send a minute before the last `updated_at` you saw.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"branch_id","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","maxLength":64}},{"name":"customer_id","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","maxLength":64}},{"name":"status","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","enum":["confirmed","cancelled","completed","no_show"]}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."},"reference":{"type":"string","description":"The code the customer sees (\"TF-K7M2Q-9XD4P\")."},"kind":{"type":"string","enum":["appointment","class"]},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"branch_id":{"type":"string"},"customer_id":{"description":"Null for a walk-in seated without a name (Tables).","type":["string","null"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"staff":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"session_id":{"description":"The class session, for a class place.","type":["string","null"]},"party_size":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang, worked out by Tellfox when booked (0 when a package pays)."},"customer_package_id":{"description":"The package that pays for it.","type":["string","null"]},"source":{"type":"string","description":"Where it was made: liff, web, owner, chat, email."},"customer_note":{"type":["string","null"]},"cancelled_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"cancelled_by":{"anyOf":[{"type":"string","enum":["customer","business"]},{"type":"null"}]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change. Use it as `updated_since`."}},"required":["id","reference","kind","status","start","end","branch_id","customer_id","service","staff","room","session_id","party_size","price","customer_package_id","source","customer_note","cancelled_at","cancelled_by","created_at","updated_at"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}},"post":{"operationId":"bookings.create","summary":"Make a booking","description":"Through the same engine as the booking page, so two bookings can never take the same time. Made by the business: no deposit; the customer gets the usual confirmation and reminders. A time taken a moment ago answers 409 with the next free times in the message. A retry with the same Idempotency-Key answers the booking it made, as it is now.\n\nScope: `bookings:write`.","tags":["Bookings"],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."},"reference":{"type":"string","description":"The code the customer sees (\"TF-K7M2Q-9XD4P\")."},"kind":{"type":"string","enum":["appointment","class"]},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"branch_id":{"type":"string"},"customer_id":{"description":"Null for a walk-in seated without a name (Tables).","type":["string","null"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"staff":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"session_id":{"description":"The class session, for a class place.","type":["string","null"]},"party_size":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang, worked out by Tellfox when booked (0 when a package pays)."},"customer_package_id":{"description":"The package that pays for it.","type":["string","null"]},"source":{"type":"string","description":"Where it was made: liff, web, owner, chat, email."},"customer_note":{"type":["string","null"]},"cancelled_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"cancelled_by":{"anyOf":[{"type":"string","enum":["customer","business"]},{"type":"null"}]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change. Use it as `updated_since`."}},"required":["id","reference","kind","status","start","end","branch_id","customer_id","service","staff","room","session_id","party_size","price","customer_package_id","source","customer_note","cancelled_at","cancelled_by","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"service_id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^svc_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"svc_…\")."},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"customer_id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"staff_id":{"description":"A person; left out: anyone who is free.","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]},"branch_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}]},"nights":{"type":"integer","minimum":1,"maximum":90},"use_package":{"description":"Pay with one of the customer’s packages that covers it.","type":"boolean"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]}},"required":["service_id","start","customer_id"]}}}}}},"/v1/availability":{"get":{"operationId":"availability.get","summary":"Free times","description":"The free start times of a service on a day (the business’s local day), as the business sees them: its own booking window does not apply. Table services are booked on the booking page.\n\nScope: `bookings:read`.","tags":["Bookings"],"parameters":[{"name":"service_id","in":"query","required":true,"description":"A Tellfox ID (\"svc_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^svc_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"svc_…\")."}},{"name":"date","in":"query","required":true,"description":"A local day, YYYY-MM-DD.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"A local day, YYYY-MM-DD."}},{"name":"branch_id","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","maxLength":64}},{"name":"staff_id","in":"query","required":false,"description":"Only this person’s times.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Only this person’s times.","type":"string","maxLength":64}},{"name":"nights","in":"query","required":false,"description":"For a stay booked by the night.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"For a stay booked by the night.","type":"integer","minimum":1,"maximum":90}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"staff_ids":{"type":"array","items":{"type":"string"},"description":"Who can do it then (any of them when you name none)."},"price":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Satang at that time (a price by time of day applies)."}},"required":["start","end","staff_ids","price"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/bookings/{booking_id}/move":{"post":{"operationId":"bookings.move","summary":"Move a booking","description":"To another free time (and person). The customer is told.\n\nScope: `bookings:write`.","tags":["Bookings"],"parameters":[{"name":"booking_id","in":"path","required":true,"description":"A Tellfox ID (\"bk_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."},"reference":{"type":"string","description":"The code the customer sees (\"TF-K7M2Q-9XD4P\")."},"kind":{"type":"string","enum":["appointment","class"]},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"branch_id":{"type":"string"},"customer_id":{"description":"Null for a walk-in seated without a name (Tables).","type":["string","null"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"staff":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"session_id":{"description":"The class session, for a class place.","type":["string","null"]},"party_size":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang, worked out by Tellfox when booked (0 when a package pays)."},"customer_package_id":{"description":"The package that pays for it.","type":["string","null"]},"source":{"type":"string","description":"Where it was made: liff, web, owner, chat, email."},"customer_note":{"type":["string","null"]},"cancelled_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"cancelled_by":{"anyOf":[{"type":"string","enum":["customer","business"]},{"type":"null"}]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change. Use it as `updated_since`."}},"required":["id","reference","kind","status","start","end","branch_id","customer_id","service","staff","room","session_id","party_size","price","customer_package_id","source","customer_note","cancelled_at","cancelled_by","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"staff_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}]}},"required":["start"]}}}}}},"/v1/bookings/{booking_id}/cancel":{"post":{"operationId":"bookings.cancel","summary":"Cancel a booking or class place","description":"Cancelled by the business (its cancellation policy does not hold the business back). The customer is told.\n\nScope: `bookings:write`.","tags":["Bookings"],"parameters":[{"name":"booking_id","in":"path","required":true,"description":"A Tellfox ID (\"bk_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."},"reference":{"type":"string","description":"The code the customer sees (\"TF-K7M2Q-9XD4P\")."},"kind":{"type":"string","enum":["appointment","class"]},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"branch_id":{"type":"string"},"customer_id":{"description":"Null for a walk-in seated without a name (Tables).","type":["string","null"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"staff":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"session_id":{"description":"The class session, for a class place.","type":["string","null"]},"party_size":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang, worked out by Tellfox when booked (0 when a package pays)."},"customer_package_id":{"description":"The package that pays for it.","type":["string","null"]},"source":{"type":"string","description":"Where it was made: liff, web, owner, chat, email."},"customer_note":{"type":["string","null"]},"cancelled_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"cancelled_by":{"anyOf":[{"type":"string","enum":["customer","business"]},{"type":"null"}]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change. Use it as `updated_since`."}},"required":["id","reference","kind","status","start","end","branch_id","customer_id","service","staff","room","session_id","party_size","price","customer_package_id","source","customer_note","cancelled_at","cancelled_by","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"reason":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]}}}}}}}},"/v1/sessions":{"get":{"operationId":"sessions.list","summary":"Class sessions","description":"Sessions starting between `from` and `to` (at most 31 days; default the next 14), soonest first, with the places left.\n\nScope: `bookings:read`.","tags":["Classes"],"parameters":[{"name":"from","in":"query","required":false,"description":"Default: now.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Default: now.","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"to","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"service_id","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","maxLength":64}},{"name":"branch_id","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","maxLength":64}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"status":{"type":"string","enum":["scheduled","cancelled"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"instructor":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"capacity":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"taken":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"spots_left":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["id","service","status","start","end","instructor","room","capacity","taken","spots_left"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/sessions/{session_id}/places":{"post":{"operationId":"sessions.join","summary":"Give a customer a place in a class","description":"A place while there is one (two at once never pass the capacity). The customer is told. Answers the place as a booking, 201 for a new place or 200 when the customer had one already (cancel it with POST /v1/bookings/{id}/cancel).\n\nScope: `bookings:write`.","tags":["Classes"],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."},"reference":{"type":"string","description":"The code the customer sees (\"TF-K7M2Q-9XD4P\")."},"kind":{"type":"string","enum":["appointment","class"]},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"branch_id":{"type":"string"},"customer_id":{"description":"Null for a walk-in seated without a name (Tables).","type":["string","null"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"staff":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"session_id":{"description":"The class session, for a class place.","type":["string","null"]},"party_size":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang, worked out by Tellfox when booked (0 when a package pays)."},"customer_package_id":{"description":"The package that pays for it.","type":["string","null"]},"source":{"type":"string","description":"Where it was made: liff, web, owner, chat, email."},"customer_note":{"type":["string","null"]},"cancelled_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"cancelled_by":{"anyOf":[{"type":"string","enum":["customer","business"]},{"type":"null"}]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change. Use it as `updated_since`."}},"required":["id","reference","kind","status","start","end","branch_id","customer_id","service","staff","room","session_id","party_size","price","customer_package_id","source","customer_note","cancelled_at","cancelled_by","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"customer_id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."},"use_package":{"type":"boolean"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]}},"required":["customer_id"]}}}}}},"/v1/bookings/{booking_id}":{"get":{"operationId":"bookings.get","summary":"A booking","description":"Scope: `bookings:read`.","tags":["Bookings"],"parameters":[{"name":"booking_id","in":"path","required":true,"description":"A Tellfox ID (\"bk_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^bk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"bk_…\")."},"reference":{"type":"string","description":"The code the customer sees (\"TF-K7M2Q-9XD4P\")."},"kind":{"type":"string","enum":["appointment","class"]},"status":{"type":"string","enum":["confirmed","cancelled","completed","no_show"]},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"branch_id":{"type":"string"},"customer_id":{"description":"Null for a walk-in seated without a name (Tables).","type":["string","null"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"staff":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"room":{"anyOf":[{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},{"type":"null"}]},"session_id":{"description":"The class session, for a class place.","type":["string","null"]},"party_size":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang, worked out by Tellfox when booked (0 when a package pays)."},"customer_package_id":{"description":"The package that pays for it.","type":["string","null"]},"source":{"type":"string","description":"Where it was made: liff, web, owner, chat, email."},"customer_note":{"type":["string","null"]},"cancelled_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]},"cancelled_by":{"anyOf":[{"type":"string","enum":["customer","business"]},{"type":"null"}]},"created_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"updated_at":{"type":"string","description":"The last change. Use it as `updated_since`."}},"required":["id","reference","kind","status","start","end","branch_id","customer_id","service","staff","room","session_id","party_size","price","customer_package_id","source","customer_note","cancelled_at","cancelled_by","created_at","updated_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/packages":{"get":{"operationId":"packages.list","summary":"Packages on sale","description":"Scope: `packages:read`.","tags":["Packages"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^pkg_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"pkg_…\")."},"name":{"type":"string"},"name_en":{"type":["string","null"]},"price":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang."},"sessions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"validity_days":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"covers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false},"description":"The services and classes it can be used for."},"sold_online":{"type":"boolean"}},"required":["id","name","name_en","price","sessions","validity_days","covers","sold_online"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers/{customer_id}/packages":{"post":{"operationId":"packages.sell","summary":"Sell a package","description":"A sale at the counter: the price comes from the package, paid by cash, transfer or card. The customer gets the usual \"package bought\" message; it earns on the loyalty card like a sale in the owner pages.\n\nScope: `packages:write`.","tags":["Packages"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cpk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cpk_…\")."},"package_id":{"type":"string"},"name":{"type":"string"},"sessions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Sessions held by bookings still to come."},"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Sessions taken by completed bookings and no-shows."},"left":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"state":{"type":"string","description":"active, used_up, expired or void."},"price_paid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang."},"bought_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"last_day":{"type":"string","description":"The last day it can be used (YYYY-MM-DD, the business’s time zone)."},"covers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}}},"required":["id","package_id","name","sessions","reserved","used","left","state","price_paid","bought_at","last_day","covers"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"package_id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^pkg_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"pkg_…\")."},"payment_method":{"type":"string","enum":["cash","transfer","card"]},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]}},"required":["package_id","payment_method"]}}}}},"get":{"operationId":"customer_packages.list","summary":"A customer's packages","description":"Newest first (at most 50), with the sessions left.\n\nScope: `packages:read`.","tags":["Packages"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","minLength":4,"maxLength":64,"pattern":"^cpk_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cpk_…\")."},"package_id":{"type":"string"},"name":{"type":"string"},"sessions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Sessions held by bookings still to come."},"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Sessions taken by completed bookings and no-shows."},"left":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"state":{"type":"string","description":"active, used_up, expired or void."},"price_paid":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang."},"bought_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"last_day":{"type":"string","description":"The last day it can be used (YYYY-MM-DD, the business’s time zone)."},"covers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["id","name"],"additionalProperties":false}}},"required":["id","package_id","name","sessions","reserved","used","left","state","price_paid","bought_at","last_day","covers"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/coupons":{"get":{"operationId":"coupons.list","summary":"Coupons to give","description":"The coupons the business set up and has switched on.\n\nScope: `loyalty:read`.","tags":["Loyalty"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Satang off, for `amount`."},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"note":{"type":["string","null"]},"valid_days":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"valid_until":{"type":["string","null"]},"branch_ids":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Where it can be used; null: every branch."}},"required":["id","name","gives","amount","percent","service_name","gift","note","valid_days","valid_until","branch_ids"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/rewards":{"get":{"operationId":"rewards.list","summary":"Rewards for points","description":"Scope: `loyalty:read`.","tags":["Loyalty"],"parameters":[],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"coupon_name":{"type":"string"}},"required":["id","name","points","coupon_name"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers/{customer_id}/rewards/{reward_id}/redeem":{"post":{"operationId":"rewards.redeem","summary":"Trade points for a reward","description":"Takes the reward’s points and gives its coupon. Not enough points answers 409.\n\nScope: `loyalty:write`.","tags":["Loyalty"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"reward_id","in":"path","required":true,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":1,"maxLength":64}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"coupon":{"anyOf":[{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false},{"type":"null"}]},"card":{"type":"object","properties":{"member":{"type":"boolean","description":"False until the customer first earns or is given something."},"stamps_on":{"type":"boolean"},"stamps":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"stamps_per_card":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points_on":{"type":"boolean"},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"coupons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false},"description":"Active coupons first, then the latest used and expired ones."}},"required":["member","stamps_on","stamps","stamps_per_card","points_on","points","coupons"],"additionalProperties":false}},"required":["coupon","card"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers/{customer_id}/loyalty":{"get":{"operationId":"loyalty.get","summary":"A customer's card","description":"Stamps, points and coupons. Empty when the business has no loyalty program.\n\nScope: `loyalty:read`.","tags":["Loyalty"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"member":{"type":"boolean","description":"False until the customer first earns or is given something."},"stamps_on":{"type":"boolean"},"stamps":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"stamps_per_card":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points_on":{"type":"boolean"},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"coupons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false},"description":"Active coupons first, then the latest used and expired ones."}},"required":["member","stamps_on","stamps","stamps_per_card","points_on","points","coupons"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/customers/{customer_id}/stamps":{"post":{"operationId":"loyalty.stamps","summary":"Give stamps","description":"Stamps on the stamp card for a visit or a purchase (1 to 10 at a time). A full card gives its reward coupon, as in the owner pages. Answers the card.\n\nScope: `loyalty:write`.","tags":["Loyalty"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"member":{"type":"boolean","description":"False until the customer first earns or is given something."},"stamps_on":{"type":"boolean"},"stamps":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"stamps_per_card":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points_on":{"type":"boolean"},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"coupons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false},"description":"Active coupons first, then the latest used and expired ones."}},"required":["member","stamps_on","stamps","stamps_per_card","points_on","points","coupons"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"count":{"default":1,"type":"integer","minimum":1,"maximum":10},"reason":{"description":"What it was for; the team sees it. Default: the key’s name.","type":"string","minLength":1,"maxLength":200},"branch_id":{"description":"The branch it happened at; a key limited to some branches must name one of its branches.","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]}}}}}}}},"/v1/customers/{customer_id}/points":{"post":{"operationId":"loyalty.points","summary":"Points for a sale","description":"For a sale made in your system: the program’s rate turns the amount spent into whole points (for example one point per ฿10). Boosts in Tellfox apply to visits booked in Tellfox, not to these.\n\nScope: `loyalty:write`.","tags":["Loyalty"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"points_added":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"card":{"type":"object","properties":{"member":{"type":"boolean","description":"False until the customer first earns or is given something."},"stamps_on":{"type":"boolean"},"stamps":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"stamps_per_card":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"points_on":{"type":"boolean"},"points":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"coupons":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false},"description":"Active coupons first, then the latest used and expired ones."}},"required":["member","stamps_on","stamps","stamps_per_card","points_on","points","coupons"],"additionalProperties":false}},"required":["points_added","card"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"amount":{"type":"integer","minimum":1,"maximum":1000000000,"description":"What the customer spent, in satang."},"reference":{"type":"string","minLength":1,"maxLength":100,"description":"Your sale’s number; the team sees it."},"branch_id":{"description":"The branch it happened at; a key limited to some branches must name one of its branches.","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]}},"required":["amount","reference"]}}}}}},"/v1/customers/{customer_id}/coupons":{"post":{"operationId":"coupons.give","summary":"Give a coupon","description":"One of the coupons the business set up (GET /v1/coupons). The customer gets the usual message on a channel they agreed to offers on. A key limited to some branches cannot give coupons (as in the owner pages).\n\nScope: `loyalty:write`.","tags":["Loyalty"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"201":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"coupon_id":{"type":"string","minLength":1,"maxLength":64}},"required":["coupon_id"]}}}}}},"/v1/customers/{customer_id}/coupons/{given_id}/use":{"post":{"operationId":"coupons.use","summary":"Use a coupon","description":"Marks one of the customer’s active coupons used (`id` from their card). A coupon is used once; a used, expired or other branch’s coupon is refused with 409.\n\nScope: `loyalty:write`.","tags":["Loyalty"],"parameters":[{"name":"customer_id","in":"path","required":true,"description":"A Tellfox ID (\"cus_…\").","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64,"pattern":"^cus_[A-Za-z0-9_-]+$","description":"A Tellfox ID (\"cus_…\")."}},{"name":"given_id","in":"path","required":true,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":1,"maxLength":64}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"This given coupon (use it with POST …/coupons/{given_id}/use)."},"coupon_id":{"type":"string"},"name":{"type":"string"},"gives":{"type":"string","enum":["amount","percent","service","gift"]},"amount":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"percent":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"service_name":{"type":["string","null"]},"gift":{"type":["string","null"]},"way":{"type":"string","description":"How it was given: gift, welcome, birthday, everyone, comeback, reward, card."},"given_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"expires_at":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["active","used","expired"]},"used_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","coupon_id","name","gives","amount","percent","service_name","gift","way","given_at","expires_at","status","used_at"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"branch_id":{"description":"The branch it happened at; a key limited to some branches must name one of its branches.","anyOf":[{"type":"string","maxLength":64},{"type":"null"}]}}}}}}}},"/v1/events":{"get":{"operationId":"events.list","summary":"Events","description":"The business’s events with tickets (the Ticketing add-on): upcoming (default), past or drafts.\n\nScope: `tickets:read`.","tags":["Tickets"],"parameters":[{"name":"tab","in":"query","required":false,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","default":"upcoming","type":"string","enum":["upcoming","past","draft"]}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before (30 a page).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before (30 a page).","type":"string","maxLength":10}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"name_en":{"type":["string","null"]},"branch_id":{"type":"string"},"start":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"end":{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},"status":{"type":"string","enum":["draft","published","unpublished","cancelled"]},"sales_on":{"type":"boolean"},"capacity":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"sold":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"link":{"type":"string","description":"The public event page."}},"required":["id","name","name_en","branch_id","start","end","status","sales_on","capacity","sold","link"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/events/{event_id}/tickets":{"get":{"operationId":"events.tickets","summary":"Who bought tickets","description":"Every ticket of the event with its buyer and check-in, 50 orders a page.\n\nScope: `tickets:read`.","tags":["Tickets"],"parameters":[{"name":"event_id","in":"path","required":true,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before (50 orders a page).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before (50 orders a page).","type":"string","maxLength":10}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"order_id":{"type":"string"},"order_reference":{"type":"string"},"buyer_name":{"type":"string"},"buyer_email":{"type":["string","null"]},"buyer_phone":{"type":["string","null"]},"type":{"type":"string"},"status":{"type":"string","enum":["held","valid","cancelled"]},"checked_in_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}]}},"required":["id","order_id","order_reference","buyer_name","buyer_email","buyer_phone","type","status","checked_in_at"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}},"/v1/events/{event_id}/check-in":{"post":{"operationId":"events.checkin","summary":"Check a ticket in at the door","description":"The code from the ticket’s QR (TF1.…), checked against Tellfox’s signature, for an event of today or tomorrow at a branch the key may use. Two doors scanning one ticket at once: one gets `ok`, the other `used`. Use a new Idempotency-Key for every scan.\n\nScope: `tickets:write`.","tags":["Tickets"],"parameters":[{"name":"event_id","in":"path","required":true,"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","minLength":4,"maxLength":64}},{"name":"Idempotency-Key","in":"header","required":true,"description":"Any unique text up to 255 characters. Sending the same request again with the same key answers the first answer and does nothing twice (kept 24 hours).","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"object","properties":{"state":{"type":"string","enum":["ok","used","cancelled","unpaid","wrong_event","not_real"],"description":"`ok`: let them in. Anything else: do not."},"ticket_id":{"type":["string","null"]},"name":{"type":["string","null"]},"type":{"type":["string","null"]},"checked_in_at":{"anyOf":[{"type":"string","description":"A time in UTC, ISO 8601 (\"2026-10-22T09:30:00Z\")."},{"type":"null"}],"description":"For `used`: when it was checked in before."},"checked_in":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Tickets checked in at this event so far."},"sold":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["state","ticket_id","name","type","checked_in_at","checked_in","sold"],"additionalProperties":false}},"required":["data"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","minLength":1,"maxLength":300}},"required":["code"]}}}}}},"/v1/payments":{"get":{"operationId":"payments.list","summary":"Confirmed payments","description":"Payments customers made by PromptPay and the business confirmed (deposits, packages bought online, ticket orders), oldest first by `paid_at`. For accounting.\n\nScope: `payments:read`.","tags":["Payments"],"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to answer, 1 to 200 (default 50).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","default":50,"description":"How many to answer, 1 to 200 (default 50).","type":"integer","minimum":1,"maximum":200}},{"name":"cursor","in":"query","required":false,"description":"`meta.next_cursor` of the page before, to read the next page.","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"`meta.next_cursor` of the page before, to read the next page.","type":"string","maxLength":400}},{"name":"from","in":"query","required":false,"description":"Confirmed at or after (UTC).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Confirmed at or after (UTC).","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}},{"name":"to","in":"query","required":false,"description":"Confirmed before (UTC).","schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","description":"Confirmed before (UTC).","type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$"}}],"responses":{"200":{"description":"Done","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["booking_deposit","package_order","ticket_order"]},"subject_id":{"type":"string","description":"The booking, package order or ticket order it paid for."},"customer_id":{"type":["string","null"]},"title":{"type":"string"},"amount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Satang."},"paid_at":{"type":"string","description":"When the business confirmed it."}},"required":["id","kind","subject_id","customer_id","title","amount","paid_at"],"additionalProperties":false}},"meta":{"type":"object","properties":{"next_cursor":{"type":["string","null"]}},"required":["next_cursor"],"additionalProperties":false}},"required":["data","meta"],"additionalProperties":false}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"field":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","request_id"],"additionalProperties":false}},"required":["error"],"additionalProperties":false}}}}}}}}}