Developer platform · v1.0 · REST + Webhooks

Build on top of relax.host.

A REST API, webhook events, native SDKs, and a sandbox environment — so you can plug relax.host into the rest of your stack, automate workflows, and build vertical experiences for your operators.

OpenAPI 3.1 spec OAuth 2.0 RFC 7807 errors Sandbox env
cURL
Node
Python
Go
Copy
1# Issue an access code for a reservation
2curl -X POST https://api.relax.host/v1/access-codes \
3 -H "Authorization: Bearer $SMARTHOST_TOKEN" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "reservation_id": "res_4892",
7 "lock_id": "lock_tatra_main",
8 "scope": "stay"
9 }'
10
11# → { "code": "4471", "valid_from": "2026-05-24T15:00", "valid_to": ... }
A

Authentication

OAuth 2.0 for apps · Personal Access Tokens for scripts.

Q

Quick start

Make your first authenticated call in under five minutes.

R

Reference

Every endpoint, parameter, and response — with examples.

W

Webhooks

32 events for reservations, messages, codes, payments.

S

Sandbox

A separate environment with fake guests and fake money.

L

SDKs

Node, Python, Go, Ruby. Postman collection included.

×

Rate limits

1000 req/min default. Burst friendly. Quotas per resource.

C

Changelog

Every API change, dated. We never break v1 silently.

Developers Introduction

One API, your operator stack.

The relax.host platform is a REST API plus a webhook fabric. You can read everything your operators see, write everything your operators can do, and subscribe to every event the agent emits.

The platform is built on the same internal API that powers the relax.host web app and mobile clients. There's no second-tier surface; you get parity with us. Everything is versioned (/v1), every change is documented, and we never break v1 silently.

Who this is for

  • Property managers running internal tooling — dashboards, reporting, custom owner portals.
  • Vertical SaaS building on top of relax.host — turnover marketplaces, cleaning platforms, lock vendors.
  • Channel partners integrating their service into relax.host-managed properties.
  • Operators wiring relax.host into their existing finance, CRM, or BI stack.

What you'll need

  • A relax.host account (any plan, including the free trial).
  • A Personal Access Token from Settings → Developers, or a registered OAuth app.
  • HTTPS — we don't accept plaintext requests, ever.
Developers Authentication

Authenticate with a token.

Two flows: Personal Access Tokens for scripts and internal tools, OAuth 2.0 for apps acting on behalf of other relax.host users.

Personal Access Tokens

Create a token at Settings → Developers → Personal access tokens. Choose a name (visible to your team), an expiry (recommended: 90 days), and a scope set. Copy the token immediately — we only show it once.

Pass the token in the Authorization header on every request:

cURL curl https://api.relax.host/v1/properties \ -H "Authorization: Bearer cs_pat_4mB2k1xQ..."

OAuth 2.0

For apps that act on behalf of other relax.host users, register at Settings → Developers → OAuth applications. You'll receive a client_id and client_secret. Use the authorization-code flow with PKCE; we don't support implicit grants.

Authorization URL

GET https://app.relax.host/oauth/authorize
ParameterTypeDescription
client_id requiredstringYour OAuth app's client ID.
redirect_uri requiredstringOne of your app's registered redirect URIs. HTTPS only.
response_type requiredstringAlways code.
scope requiredstringSpace-separated list of scopes. See scopes.
statestringOpaque value returned with the response. Use for CSRF protection.
code_challenge requiredstringPKCE challenge. Use SHA-256.

Scopes

ScopeGrants
properties:readList and read properties.
properties:writeCreate, update, archive properties.
reservations:readList and read reservations.
reservations:writeCancel, modify dates, add notes.
messages:readRead all message threads.
messages:writeSend messages on behalf of the user.
access:writeGenerate and revoke access codes.
accounting:readRead invoices and expense data.
webhooks:manageCreate and update webhook endpoints.
Tip · least privilege Request only the scopes your app needs. relax.host's OAuth consent screen highlights overscoped apps to end users, which hurts conversion.
Developers Quick start

Your first five minutes.

Three calls: list your properties, fetch the latest reservation, and issue an access code.

1 · List properties

GET https://api.relax.host/v1/properties
cURL curl https://api.relax.host/v1/properties \ -H "Authorization: Bearer $SMARTHOST_TOKEN" # → { # "data": [ # { # "id": "prop_tatra_loft", # "name": "Tatra Loft", # "address": "Hlavné námestie 12, Bratislava", # "channels": ["airbnb", "booking"], # "access_type": "smart_lock", # "autonomy_level": "supervised" # }, # ... # ], # "next_cursor": null # }

2 · Fetch a reservation

GET https://api.relax.host/v1/reservations/{id}
Node import SmartHost from '@smart-host/sdk'; const host = new SmartHost({ token: process.env.SMARTHOST_TOKEN }); const res = await host.reservations.get('res_4892'); console.log(res.guest.name, res.checkin, res.checkout);

3 · Issue an access code

POST https://api.relax.host/v1/access-codes
Python import smarthost smarthost.api_key = os.environ['SMARTHOST_TOKEN'] code = smarthost.AccessCode.create( reservation_id='res_4892', lock_id='lock_tatra_main', scope='stay', deliver_at='2026-05-24T13:00:00Z', ) print(code.code, code.valid_from, code.valid_to)
Done That's the platform. Read, fetch, mutate. The rest of this doc is reference — every other endpoint follows the same shape.
Developers Environments

Two environments.

Every relax.host account gets a production and a sandbox workspace. They share user logins and OAuth apps but are otherwise fully isolated — different data, different webhooks, different rate limits.

EnvironmentBase URLPurpose
Productionapi.relax.hostReal properties, real guests, real money.
Sandboxapi.sandbox.relax.hostFake properties, fake guests, fake money. Channels simulated.

Token prefixes tell you which environment you're hitting:

  • cs_pat_* — production personal access token
  • cs_sandbox_pat_* — sandbox personal access token
  • cs_live_* / cs_sandbox_* — OAuth access tokens
Developers Errors

RFC 7807 errors.

Every error response uses the Problem Details shape. You get a stable machine-readable type, a human-readable title, and a contextual detail message.

JSON { "type": "https://errors.relax.host/reservations/not-found", "title": "Reservation not found", "status": 404, "detail": "No reservation with id 'res_4892' in this workspace.", "instance": "req_8K3xQwMz", "docs": "https://docs.relax.host/api/errors#not-found" }
StatusMeaningRetriable
400Bad request — your payload is malformed or fails validation.No (fix and retry)
401Unauthorized — token missing, expired, or revoked.No
403Forbidden — token valid but lacks scope, or accessing another workspace.No
404Resource not found in your workspace.No
409Conflict — stale state or duplicate idempotency key with different payload.No (read fresh state)
422Validation failure — see errors[] for per-field details.No
429Rate limited. Honour Retry-After.Yes
5xxrelax.host is having a bad day. We're paged.Yes (exp. backoff)
Developers Rate limits

Generous by default.

relax.host's default rate limit is 1,000 requests per minute per workspace with burst headroom. Webhook deliveries don't count against your quota.

Every response includes rate-limit headers:

Headers X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 982 X-RateLimit-Reset: 1747381200 Retry-After: 5 # only on 429
Resource-specific limits /messages writes are capped at 60/minute per workspace to prevent inadvertent guest spam. Bulk message imports use a separate batch endpoint.
Developers Idempotency

Retry safely.

All POST and DELETE endpoints accept an Idempotency-Key header (any string, max 256 chars). The first request with a given key is processed; subsequent requests with the same key return the original response.

Keys live for 24 hours. Use a UUID per logical request. If you replay with the same key but a different payload, you get a 409.

Developers API reference

Reference.

Every endpoint, every parameter, every response. The full machine-readable OpenAPI 3.1 spec is also at openapi.relax.host/v1.yaml.

Properties Stable

A property is a single listing under relax.host management. Properties have channels, an access type, an autonomy level, and a memory of their own.

GET /v1/properties

List all properties in your workspace.

GET /v1/properties/{id}

Fetch a single property by ID.

PUT /v1/properties/{id}

Update mutable property fields.

Property object

FieldTypeDescription
idstringStable identifier. Prefix: prop_.
namestringHuman-readable name.
addressobjectPostal address. See address shape.
channelsstring[]Connected channels. One of airbnb, booking, vrbo, direct.
access_typeenumsmart_lock, keypad, lockbox, key_handoff, doorman.
autonomy_levelenumautonomous, supervised, manual, custom.
check_in_timetimeISO-8601 time-of-day. Default "15:00".
tone_profilestringTone preset or freeform brief.
created_atdatetimeCreation timestamp.

Reservations Stable

One row per booking, regardless of channel.

GET /v1/reservations?property_id={id}&status=upcoming

List reservations, optionally filtered.

GET /v1/reservations/{id}
POST /v1/reservations/{id}/notes

Messages Stable

GET /v1/reservations/{id}/messages
POST /v1/reservations/{id}/messages

Send a message into the reservation thread. relax.host relays to the channel; you get a delivery receipt on the message.delivered webhook.

Access codes Stable

POST /v1/access-codes
DEL /v1/access-codes/{id}

Revoke a code immediately (e.g. a guest cancels after check-in).

Pricing Beta

Read and set nightly rates, floor/ceiling guardrails, and pricing rules.

GET /v1/properties/{id}/pricing
PUT /v1/properties/{id}/pricing/guardrails

Invoices & expenses Stable

GET /v1/invoices?period=2026-05
POST /v1/expenses

Submit an expense. Pass a receipt image as multipart and relax.host parses the line items.

Developers Webhooks

Subscribe to every event.

Webhooks let your app react in real time — without polling. relax.host posts a signed JSON payload to your HTTPS endpoint within seconds of the event.

Create a subscription

POST /v1/webhook-endpoints
cURL curl -X POST https://api.relax.host/v1/webhook-endpoints \ -H "Authorization: Bearer $SMARTHOST_TOKEN" \ -d '{ "url": "https://example.com/smarthost/webhook", "events": ["reservation.created", "message.received", "review.posted"], "description": "Production receiver" }' # → { "id": "we_8K3...", "signing_secret": "whsec_..." }

Event catalog

Each event fires when the corresponding state change is committed. Events are at-least-once delivered.

Reservations

reservation.created reservation.modified reservation.cancelled reservation.checked_in reservation.checked_out reservation.no_show

Messages

message.received message.sent message.delivered message.failed message.flagged_for_review

Access & operations

access_code.issued access_code.delivered access_code.revoked cleaning.scheduled cleaning.confirmed cleaning.completed maintenance.flagged

Pricing & revenue

price.updated payout.created invoice.issued expense.parsed

Guests & reviews

guest.mood_changed review.posted review.responded

Signature verification

Every webhook payload is signed with HMAC-SHA256 using your endpoint's signing secret. Verify the relax.host-Signature header before processing.

Node import { verifyWebhook } from '@smart-host/sdk'; app.post('/smarthost/webhook', (req, res) => { try { const event = verifyWebhook({ payload: req.rawBody, signature: req.headers['relax.host-signature'], secret: process.env.SMARTHOST_WEBHOOK_SECRET, }); // → safe to use event handler(event); res.sendStatus(200); } catch (e) { res.sendStatus(400); } });

Retries & delivery

If your endpoint returns a 2xx, the event is marked delivered. Anything else triggers a retry with exponential backoff over 24 hours (up to 9 attempts: 1m, 2m, 4m, 8m, 16m, 32m, 1h, 4h, 12h).

After 24 hours of failures we stop and surface the failure in Settings → Developers → Webhook log. Replay any failed delivery from there with a click.

Tip · respond fast, process later Acknowledge the webhook within 5s and process asynchronously. We treat >5s responses as soft failures and retry.
Developers Integrations

Pre-built integrations.

relax.host ships with first-class connectors for the platforms most operators already use. If yours isn't here, the REST API + webhooks cover the rest.

Channel managers (read-only mode)

If you're trialling relax.host alongside an existing PMS, we listen to its webhooks rather than taking over the channel. Supported out of the box:

  • Hostaway — full reservation + message ingestion
  • Hospitable (formerly Smartbnb) — full
  • Guesty (Lite & Pro) — full
  • Smoobu — reservations only (Smoobu doesn't expose messages)
  • Lodgify — reservations only

Smart locks & access

Native two-way integrations:

  • August · Nuki · TTLock · Yale (via Salto Homelok) · Igloohome · Schlage Encode (beta)
  • Salto Homelok · SmartThings · Aqara hubs
  • Static keypads & lockboxes — managed by relax.host memory, no integration needed

Accounting exports

  • QuickBooks Online — auto-sync invoices & expenses
  • Xero — auto-sync invoices & expenses
  • FreeAgent · Pohoda · iDoklad — CSV bundle on the first of the month
  • Generic CSV / OFX export from any month

Zapier & Make

For workflows that don't need a custom integration, the relax.host Zapier and Make apps cover the most common triggers and actions:

  • Trigger: new reservation, new message, new review, new payout
  • Action: send message, issue code, log expense, add note

Both apps support the sandbox environment so you can build flows without touching production.

Developers Sandbox

The sandbox is real.

Every relax.host account gets a sandbox workspace with simulated channels, fake guests, and a scriptable event timeline.

In sandbox:

  • Airbnb & Booking.com are simulated. You can fire fake reservations, messages, and reviews from the developer console.
  • Smart locks return synthetic codes. Real lock hardware isn't called.
  • Payments are simulated — no real money moves.
  • Webhooks fire identically to production. Build and test your full integration without risk.

Simulating events

POST https://api.sandbox.relax.host/v1/simulate/reservation

Trigger a synthetic reservation. Optionally pre-populate guest history, language, mood, and channel.

cURL curl -X POST https://api.sandbox.relax.host/v1/simulate/reservation \ -H "Authorization: Bearer $SMARTHOST_SANDBOX_TOKEN" \ -d '{ "property_id": "prop_demo_loft", "channel": "airbnb", "guest_name": "Test Guest", "guest_lang": "de", "checkin": "2026-06-01T15:00", "nights": 3 }'
Developers SDKs & tools

SDKs, typed and tiny.

LanguagePackageStatus
Node.js / TypeScriptnpm i @smart-host/sdkStable · v1.4
Pythonpip install smarthostStable · v1.3
Gogo get github.com/relax.host-ai/relax.host-goStable · v1.2
Rubygem install smarthostBeta · v0.9
PHPcomposer require smart-host/smarthost-phpBeta · v0.7
OpenAPI specopenapi.relax.host/v1.yamlAlways current
Postman collectionRun in Postman ↗Always current

CLI

Shell brew install smarthost/tap/relax.host relax.host login relax.host properties list relax.host reservations show res_4892 relax.host webhook tail # stream events live
Developers Changelog

API changelog.

Every visible change to the public API, dated. We never break v1 silently — additive changes are flagged additive, breaking changes get a new version.

DateChangeType
2026-05-12Added guest.mood_changed webhook eventAdditive
2026-05-03POST /v1/access-codes accepts deliver_at overrideAdditive
2026-04-22Pricing endpoints promoted to public betaBeta
2026-04-08Webhook retry window extended from 12h → 24hBehavior
2026-03-19Sandbox channel simulator GAGA
2026-02-04Public launch · v1 frozenLaunch
RSS / Webhook for changelog Subscribe at changelog.relax.host/feed or wire your own listener to api.changed.
Developers Support

Talk to a human.

Open a developer ticket from Settings → Developers → Support — replies within one business day, faster on paid plans. For urgent issues, write to developers@relax.host.

Public-facing community at community.relax.host. The relax.host engineering team is active there daily.