Managing Locations
Managing Locations
A location is a physical clinic or site within your tenant. Every appointment, room, and schedule template references a location, so creating at least one location is a prerequisite for booking. This page covers the full locations CRUD.
All endpoints require the x-api-key header and use application/json request
and response bodies. Locations are tenant-scoped: you only ever see and modify
locations that belong to your own API key.
Endpoints
| Method | Path | Status | Description |
|---|---|---|---|
POST | /v1/scheduling/locations | 201 | Create a location |
GET | /v1/scheduling/locations | 200 | List locations (cursor-paginated) |
GET | /v1/scheduling/locations/{id} | 200 | Get a location by ID |
PUT | /v1/scheduling/locations/{id} | 200 | Update a location (partial) |
DELETE | /v1/scheduling/locations/{id} | 204 | Deactivate a location (soft-delete) |
The location object
| Field | Type | Description |
|---|---|---|
id | UUID | Location identifier |
name | string | Display name |
address | string or null | Street address |
city | string or null | City |
state | string or null | Brazilian state (UF, 2 letters — e.g. SP, RJ) |
zip_code | string or null | Postal code (free format, e.g. 01310-100) |
phone | string or null | Contact phone |
timezone | string | IANA timezone name (default America/Sao_Paulo) |
is_active | boolean | false after a soft-delete |
operating_hours | object | Weekly opening hours (see below) |
metadata | object | Free-form key/value metadata |
created_at | datetime | Creation timestamp (UTC) |
updated_at | datetime | Last update timestamp (UTC) |
operating_hours
operating_hours is a free-form object. The canonical shape is a map of weekday
to { "start": "HH:MM", "end": "HH:MM" }, with null for closed days:
{ "monday": { "start": "08:00", "end": "18:00" }, "tuesday": { "start": "08:00", "end": "18:00" }, "wednesday": { "start": "08:00", "end": "18:00" }, "thursday": { "start": "08:00", "end": "18:00" }, "friday": { "start": "08:00", "end": "18:00" }, "saturday": null, "sunday": null}Create a location
POST /v1/scheduling/locationsRequest body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | — | 1–255 characters |
address | string | No | null | Street address |
city | string | No | null | City (max 100 chars) |
state | string | No | null | Brazilian UF (max 2 chars) |
zip_code | string | No | null | Postal code (max 10 chars) |
phone | string | No | null | Phone (max 20 chars) |
timezone | string | No | America/Sao_Paulo | IANA timezone name (max 50 chars) |
operating_hours | object | No | clinic default | Weekly opening hours |
metadata | object | No | {} | Free-form metadata |
Only name is required; every other field has a sensible default.
Status codes
| Code | Meaning |
|---|---|
201 | Location created |
422 | Validation error (e.g. empty name, state longer than 2 characters) |
curl -X POST "https://your-instance.delphos.app/v1/scheduling/locations" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Clínica Centro", "address": "Av. Paulista, 1000", "city": "São Paulo", "state": "SP", "zip_code": "01310-100", "phone": "+5511999999999", "timezone": "America/Sao_Paulo" }'import httpx
response = httpx.post( "https://your-instance.delphos.app/v1/scheduling/locations", headers={"x-api-key": "YOUR_API_KEY"}, json={ "name": "Clínica Centro", "address": "Av. Paulista, 1000", "city": "São Paulo", "state": "SP", "zip_code": "01310-100", "phone": "+5511999999999", "timezone": "America/Sao_Paulo", },)location = response.json()location_id = location["id"]The id returned here is the value you pass as location_id when creating
appointments, schedule templates, and rooms.
List locations
GET /v1/scheduling/locationsReturns active locations by default, newest first, using cursor pagination.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Page size (1–100) |
cursor | string | — | Opaque cursor from a previous response’s next_cursor |
include_inactive | boolean | false | Include soft-deleted locations |
city | string | — | Filter by city (max 100 chars) |
Response
| Field | Type | Description |
|---|---|---|
items | array | Page of location objects |
next_cursor | string or null | Pass as cursor to fetch the next page; null on the last page |
has_more | boolean | true when more pages remain |
curl "https://your-instance.delphos.app/v1/scheduling/locations?limit=20" \ -H "x-api-key: YOUR_API_KEY"import httpx
response = httpx.get( "https://your-instance.delphos.app/v1/scheduling/locations", headers={"x-api-key": "YOUR_API_KEY"}, params={"limit": 20},)page = response.json()for location in page["items"]: print(location["id"], location["name"])
# Fetch the next page if there is oneif page["has_more"]: next_page = httpx.get( "https://your-instance.delphos.app/v1/scheduling/locations", headers={"x-api-key": "YOUR_API_KEY"}, params={"limit": 20, "cursor": page["next_cursor"]}, ).json()Get a location
GET /v1/scheduling/locations/{id}Returns a single location by ID, regardless of whether it is active or
soft-deleted (so you can reactivate it). Returns 404 if the ID does not exist
within your tenant.
curl "https://your-instance.delphos.app/v1/scheduling/locations/550e8400-e29b-41d4-a716-446655440004" \ -H "x-api-key: YOUR_API_KEY"import httpx
response = httpx.get( "https://your-instance.delphos.app/v1/scheduling/locations/550e8400-e29b-41d4-a716-446655440004", headers={"x-api-key": "YOUR_API_KEY"},)location = response.json()Update a location
PUT /v1/scheduling/locations/{id}Updates are partial — send only the fields you want to change. Omitted
fields keep their current values. Every field from the create body is accepted,
plus is_active (used to reactivate a soft-deleted location).
Status codes
| Code | Meaning |
|---|---|
200 | Location updated |
404 | No location with that ID in your tenant |
422 | Validation error |
curl -X PUT "https://your-instance.delphos.app/v1/scheduling/locations/550e8400-e29b-41d4-a716-446655440004" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "phone": "+5511988887777" }'import httpx
response = httpx.put( "https://your-instance.delphos.app/v1/scheduling/locations/550e8400-e29b-41d4-a716-446655440004", headers={"x-api-key": "YOUR_API_KEY"}, json={"phone": "+5511988887777"},)location = response.json()Reactivating a location
A soft-deleted location is reactivated by setting is_active back to true:
curl -X PUT "https://your-instance.delphos.app/v1/scheduling/locations/{id}" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "is_active": true }'Deactivate a location
DELETE /v1/scheduling/locations/{id}Deactivation is a soft-delete: the location’s is_active is set to false
and it is excluded from the default list, but the record is preserved. This is
idempotent — deleting an already-inactive location still returns 204.
Status codes
| Code | Meaning |
|---|---|
204 | Location deactivated (no response body) |
404 | No location with that ID in your tenant |
curl -X DELETE "https://your-instance.delphos.app/v1/scheduling/locations/550e8400-e29b-41d4-a716-446655440004" \ -H "x-api-key: YOUR_API_KEY"import httpx
response = httpx.delete( "https://your-instance.delphos.app/v1/scheduling/locations/550e8400-e29b-41d4-a716-446655440004", headers={"x-api-key": "YOUR_API_KEY"},)assert response.status_code == 204Errors
| Code | Meaning |
|---|---|
401 | Missing or invalid x-api-key |
404 | The location does not exist within your tenant |
422 | Request validation failed (the body lists the offending fields) |
500 | Unexpected server error |
A request for a location that belongs to a different tenant returns 404, not
403 — locations outside your tenant are simply invisible to your API key.