OhMyDesk Booking API
Read a space's live availability and create desk bookings straight from your own website,
widget, or automations. Served from ohmydesk.app — no backend URLs to wire up.
Base URL
https://ohmydesk.app/api/v1 Format
JSON, envelope { data, error, meta }
Auth
Public endpoints need no key; the rest use a per-space API key
Authentication
There are two tiers. Public endpoints — availability and desk bookings for a space — take no key and are safe to call from a browser or a public website, since they expose only what a space already publishes on its booking page. Everything else is authenticated with a per-organization API key.
Create and revoke keys in Settings → Integrations → API (owners and admins).
Send the key as a bearer token — or the x-api-key header:
Authorization: Bearer omd_live_… Get public availability
GET/public/{slug}/availability
Returns the space's desks (grouped by room), meeting rooms, private offices, and the currently
booked slots. slug is the space's public booking slug — the last segment of its
/book/<slug> page. This is the same read the public booking page and the
embeddable widget use.
curl https://ohmydesk.app/api/v1/public/your-space/availability
The data object contains org, rooms[] (each with
desks[] carrying deskId and label),
meetingRooms[], privateOffices[], and bookedSlots[]
(each { deskId, date }).
Create a desk booking
POST/public/{slug}/bookings
Books a free desk for each requested date. A desk is auto-assigned per date from live availability — you don't pick a specific desk. The space's operator is notified (and the visitor too, if you include an email), exactly as if the booking came through the space's own page.
curl -X POST https://ohmydesk.app/api/v1/public/your-space/bookings \
-H "Content-Type: application/json" \
-H "Idempotency-Key: booking-2026-07-20-ada" \
-d '{
"dates": ["2026-07-20", "2026-07-21"],
"visitorName": "Ada Lovelace",
"visitorEmail": "[email protected]",
"visitorPhone": "+359 888 123 456",
"notes": "Prefers a quiet corner"
}' Body
dates— array ofYYYY-MM-DD, at least one, each within the space's window. requiredvisitorName— who the booking is for. requiredvisitorEmail— optional; when present the visitor gets a confirmation email.visitorPhone— optional.notes— optional free-text note for the operator.
Response — 201 Created
{
"data": {
"bookings": [
{ "date": "2026-07-20", "deskId": "room2-desk4", "deskLabel": "Desk 8" },
{ "date": "2026-07-21", "deskId": "room1-desk2", "deskLabel": "Desk 2" }
]
},
"error": null,
"meta": { "slug": "your-space" }
} Idempotency
Send an Idempotency-Key header with any booking POST to make it safe
to retry. The first request with a given key does the work and stores its result; any later
request with the same key replays that stored response instead of creating a second
booking. Use a fresh, unique key for each distinct booking attempt (a UUID works well).
Without an Idempotency-Key, a repeated POST creates a new booking
each time — so always send one if the caller might retry.
Your organization (authenticated)
GET/ API key
Confirms your API key and returns the organization it belongs to — a handy smoke test.
curl https://ohmydesk.app/api/v1 \
-H "Authorization: Bearer omd_live_…" GET/availability API key
Your own organization's availability, in the same shape as the public read above.
Errors
Errors use the same envelope with data: null and an error object.
Date-specific errors also carry the offending date.
{
"data": null,
"error": {
"code": "no_desks_available",
"message": "No desks are available on 2026-07-20. Please adjust the dates.",
"date": "2026-07-20"
}
} | Code | HTTP | Meaning |
|---|---|---|
missing_visitor_name | 400 | No visitorName was supplied. |
no_dates | 400 | The dates array was empty. |
invalid_date | 400 | A date was not a valid YYYY-MM-DD. |
date_out_of_range | 400 | A date is in the past or beyond the space's booking window. |
invalid_body | 400 | The request body was not valid JSON. |
org_not_found_or_disabled | 404 | Unknown space, or public booking is turned off. |
no_desks_available | 409 | Every desk is taken on one of the requested dates. |
processing | 409 | A booking with this Idempotency-Key is still being processed. |
unauthorized | 401 | No API key was sent on an authenticated endpoint. |
invalid_key | 401 | The API key is unknown or has been revoked. |
What's next
Availability and desk bookings are live today. Read endpoints for meeting rooms, offices and members — plus authenticated writes — are on the way. Questions or early access? Email [email protected].