Property managersHosts
Features Integrations AI Pricing FAQ
Log in Create my account
Features Integrations AI Pricing FAQ Comparisons Are you a host? Try the demo Log in Create my account

OmniStay API

Version 1 · Last updated: 22 October 2026

Connect your other software to OmniStay: accounting, dashboards, maintenance tools, Zapier or Make. The API gives access to your properties, bookings, jobs, owners and team, and lets you act: jobs, quotes, invoices, calendar, prices… Webhooks notify your software as soon as a booking, a message or a job comes in. Your AI (ChatGPT, Claude, Gemini) can connect too, through the MCP server.

At a glanceCreate a keyAuthenticateResources ListingsBookingsJobsCreate a job ActionsConnected AI (MCP)WebhooksZapier and Make Owners and teamLists and paginationErrorsLimits and security

At a glance

  • Base URL: https://escale-roan.vercel.app/api/v1
  • Format: JSON in UTF-8. Dates use the AAAA-MM-JJ format (year-month-day), times HH:MM (Paris time), amounts in euros.
  • Authentication: an API key for your company in the Authorization: Bearer esk_… header.
  • Permissions: each key is either read-only or read and write (to act: create jobs, and the 91 actions).
  • Connected AI: MCP server at https://app.omnistay.ai/mcp, OAuth or API key connection (details).
  • Limit: 120 calls per minute per key.

Create a key

  1. In OmniStay, open Settings › API keys. Only the account owner and administrators have access.
  2. Give the key the name of the software to connect, and allow writing only if that software needs to act in OmniStay.
  3. Copy the key straight away: it starts with esk_ and is only shown once. OmniStay only keeps a fingerprint of it.
  4. A key you no longer use, or that someone else may have seen: revoke it. It stops working immediately.

Authenticate

Every call carries the key. To check that it works:

curl https://escale-roan.vercel.app/api/v1/me \
  -H "Authorization: Bearer esk_VOTRE_CLE"
{
  "data": {
    "organization": { "id": "11111111-1111-4111-8111-111111111111", "name": "Les Clés du Canal" },
    "key": { "name": "Comptabilité", "prefix": "esk_Ab12Cd", "scopes": ["read"] }
  }
}

The X-Api-Key: esk_… header is also accepted.

Resources

MethodEndpointWhat it returns
GET/meYour company and the key used
GET/properties, /properties/{id}Listings
GET/bookings, /bookings/{id}Bookings
GET/missions, /missions/{id}Jobs: cleaning, keys, maintenance…
POST/missionsCreates a job (key with write permission)
GET/actionsThe 91 actions, with their parameter schemas
POST/actions/{nom}Runs an action (key with write permission to act)
POST/webhooksSubscribes a URL to events (webhooks)
GET/webhooks, /webhooks/{id}Subscriptions created with this key
DELETE/webhooks/{id}Deletes a subscription
GET/owners, /owners/{id}Owners
GET/team, /team/{id}Team

Listings

GET /properties
{
  "data": [{
    "id": "p1", "name": "Loft Canal Saint-Martin", "internal_name": "Valmy 3e G", "type": "appartement", "status": "active",
    "address": { "street": "42 quai de Valmy", "zip": "75010", "city": "Paris" },
    "surface_m2": 58,
    "capacity": { "guests": 4, "double_beds": 1, "single_beds": 0, "sofa_beds_double": 1, "sofa_beds_single": 0 },
    "check_in": { "from": "16:00", "until": "23:00", "mode": "lockbox" }, "check_out": "11:00",
    "platforms": ["airbnb", "booking"], "base_price": 145, "cleaning_fee": 70,
    "owner_id": "c1", "created_at": "2026-10-17", "updated_at": "2026-10-17T09:12:44.512Z"
  }],
  "total": 6, "limit": 100, "offset": 0
}

Access codes (key box, lock) and Wi-Fi are never returned by the API.

Bookings

GET /bookings?from=2026-10-01&to=2026-11-01&property_id=p1
FilterEffect
from, toBookings that overlap the period: checkout after from, check-in before to
property_idA single property
statusconfirmed ou cancelled
updated_sinceOnly what has changed since an ISO 8601 date and time (2026-10-17T09:00:00Z): handy for syncing
{
  "data": [{
    "id": "cx_8f2a", "property_id": "p1", "platform": "airbnb", "reference": "HMX4K2P9QA", "status": "confirmed",
    "check_in": "2026-10-17", "check_out": "2026-10-21", "nights": 4, "arrival_time": "16:30", "departure_time": null,
    "guest": { "first_name": "Camille", "last_name": "Laurent", "email": "camille@exemple.fr", "phone": "+33 6 12 34 56 78",
               "language": "fr", "country": "France", "count": 2 },
    "amounts": { "currency": "EUR", "guest_paid": 690.8, "accommodation": 600, "nightly": 150, "cleaning": 70, "linen": 15,
                 "tourist_tax": 20.8, "platform_fees": 103.85, "payout": 566.15, "tax_collected_by_platform": true },
    "created_at": "2026-09-30", "updated_at": "2026-10-16T18:02:11.870Z"
  }],
  "total": 1, "limit": 100, "offset": 0
}

The checkout day (check_out) is not a booked night. platform is airbnb, booking, vrbo, expedia, direct or manual.

Jobs

GET /missions?from=2026-10-20&to=2026-10-31&type=cleaning

Filters: from and to (job date, inclusive), property_id, member_id, type, status, updated_since.

{
  "data": [{
    "id": "cl_8f2a", "type": "cleaning", "title": "Ménage de fin de séjour", "description": null,
    "property_id": "p1", "booking_id": "cx_8f2a", "member_id": "t1",
    "date": "2026-10-21", "time": "11:00", "duration": "02:30", "pay": 55, "billed": 70, "status": "accepted",
    "report": null, "created_at": "2026-09-30", "updated_at": "2026-10-16T18:02:12.004Z"
  }],
  "total": 1, "limit": 100, "offset": 0
}
FieldValues
typecleaning (cleaning), keys (keys), diy, linen, plumbing, electricity, photo, delivery, pool, tour, decoration, pests, hvac, taxi, massage, food, babysitting, pets, housekeeper, other
statusunassigned, offered (offered), accepted, done (done, awaiting approval), validated, cancelled
pay, billedPaid to the worker, and recharged to the owner (euros)
reportAfter the job: number of photos, comment, duration in minutes, missing items and damage

Create a job

With a key that has write permission. The job is offered to the chosen person (member_id), otherwise to the property’s team; they accept it in their app, and the job appears in OmniStay straight away.

curl -X POST https://escale-roan.vercel.app/api/v1/missions \
  -H "Authorization: Bearer esk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{ "type": "plumbing", "property_id": "p1", "date": "2026-10-18", "time": "09:00",
        "member_id": "t2", "description": "Fuite sous l’évier de la cuisine" }'
FieldRequiredDefault
property_idYes—
dateYes—
typeNocleaning
timeNoThe property’s checkout time for a cleaning, 16:00 for keys, 10:00 otherwise
durationNoThe property’s cleaning duration, otherwise 02:00
pay, billedNoThe property’s settings for a cleaning
member_id, booking_idNoNone
title, descriptionNoThe name of the job type

Response 201 with the created job, in the same format as GET /missions.

Actions

Everything the AI Assistant can do in OmniStay also goes through the API: 91 actions (quotes, invoices, bookings, calendar, prices, jobs, team and absences, owners, properties, messages, reviews, deposits, incidents, damage and disputes, prospects, revenue estimates, guest welcome and scheduled messages, tourist tax, booking statistics and forecast…), with the same controls: permissions of the person who created the key, journal, undo for 24 hours from the app. The list, with each action’s JSON parameter schema:

curl https://escale-roan.vercel.app/api/v1/actions \
  -H "Authorization: Bearer esk_VOTRE_CLE"
{ "data": [{ "name": "creer_devis", "title": "Créer un devis", "module": "Facturation", "kind": "write", "confirmation": false,
             "description": "…", "input_schema": { "type": "object", "properties": { … } },
             "method": "POST", "path": "/api/v1/actions/creer_devis" }], "total": 91 }

To run an action, send its parameters as JSON:

curl -X POST https://escale-roan.vercel.app/api/v1/actions/creer_devis \
  -H "Authorization: Bearer esk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{ "client": "Sophie Martin", "objet": "Ménage de printemps",
        "lignes": [{ "designation": "Grand ménage", "prix_unitaire": 120 }] }'
{ "status": "done", "message": "Devis en brouillon pour Sophie Martin : « Ménage de printemps »…",
  "data": { "id": "doc_…" }, "url": "https://app.omnistay.ai/app/#/facturation/document/doc_…", "journal_id": "…" }
  • Response 201 when the action is done ("status": "done"), 200 for a read ("status": "ok").
  • Add "dry_run": true to see what the action would do, without changing anything: response "status": "preview" with the preview.
  • Actions with "confirmation": true send something or can’t be undone (issuing an invoice, sending a message, calendar and prices sent to the platforms, charging a deposit…). Through the API, they’re carried out as soon as they’re called: try them with dry_run first.
  • Actions with "kind": "write" require a key with write permission. Never any access code or Wi-Fi password in the responses.

Connected AI (MCP)

OmniStay is an MCP (Model Context Protocol) server: ChatGPT, Claude, Gemini, Claude Code, Gemini CLI or your own agents read and act in OmniStay with the 91 actions above, as tools. Running OmniStay from an AI is part of the AI Assistant add-on.

  • URL: https://app.omnistay.ai/mcp (streamable HTTP, JSON responses, no session).
  • Protocol versions: 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25 and 2026-07-28.
  • OAuth 2.1 connection (ChatGPT, Claude, Gemini): discovery through /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server, dynamic client registration (/oauth/register) or client metadata document, PKCE S256 required, resource-bound tokens, refresh with rotation. The person logs in, chooses their company and can allow read access only; they disconnect the AI with one tap in Settings › API keys.
  • API key connection (Claude Code, Gemini CLI, your agents): Authorization: Bearer esk_… header.
  • Confirmation: tools that send something or can’t be undone have a confirmer parameter. Without it, they do nothing and return a preview starting with “Rien n’est fait” (nothing has been done); the AI shows it to the person, then calls the tool again with "confirmer": true once they agree.
  • Journal: every action is logged in Settings › AI journal, in the name of the person who connected the AI, and can be undone for 24 hours. 120 calls per minute per connected AI.

Claude Code:

claude mcp add --transport http omnistay https://app.omnistay.ai/mcp \
  --header "Authorization: Bearer esk_VOTRE_CLE"

Gemini CLI, in ~/.gemini/settings.json:

{ "mcpServers": { "omnistay": { "httpUrl": "https://app.omnistay.ai/mcp",
                                "headers": { "Authorization": "Bearer esk_VOTRE_CLE" } } } }

ChatGPT, Claude and Gemini: the up-to-date steps are in OmniStay, Settings › API keys.

Webhooks

OmniStay notifies your software as soon as something happens: it sends a JSON POST to the URL you provide. Subscribe in the app (Settings › Integrations, with “Send a test” and the latest deliveries) or through the API with a key, following the REST Hooks model.

EventWhen
booking.createdAn upcoming booking comes in: platform, direct booking or entered manually. A booking made on a property manager’s or host’s website is sent once paid, never while it’s awaiting payment (nor if it’s cancelled before)
booking.updatedDates, property, check-in or checkout times, guest or amounts changed (several changes before delivery: a single delivery, the most recent)
booking.cancelledA booking is cancelled
precheckin.completedThe guest has completed their pre-check-in: data.precheckin (completed_at, guests, forms), never the police registration forms
message.receivedA new message from a guest, a message sent (text, translation, sent_at)
review.receivedA new review: kind is review (platform) or first_impression (guest app)
incident.openedA guest reports a problem (hot water, keys, Wi-Fi, leak…)
mission.created, mission.accepted, mission.doneAn upcoming job is created, taken by someone on the team, completed (with its report)
invoice.issuedAn invoice, a deposit invoice or a credit note gets its number: source is invoicing (Invoicing) or owner_statement (an owner’s monthly invoice)
lead.receivedSomeone fills in the form on your showcase website

Past stays and jobs, old reviews and messages, and anything added by an import from previous software trigger nothing.

What your URL receives

POST https://votre-outil.exemple.fr/omnistay
Content-Type: application/json; charset=utf-8
User-Agent: OmniStay-Webhooks/1.0
X-OmniStay-Event: booking.created
X-OmniStay-Event-Id: evt_6f1c0b7e2d4a4c1f9b3e8d5a7c2f1e09
X-OmniStay-Delivery: 1842
X-OmniStay-Signature: t=1792656000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd

{
  "id": "evt_6f1c0b7e2d4a4c1f9b3e8d5a7c2f1e09",
  "type": "booking.created",
  "created_at": "2026-10-22T09:14:03Z",
  "test": false,
  "organization": { "id": "11111111-1111-4111-8111-111111111111", "name": "Les Clés du Canal" },
  "data": {
    "id": "cx_8f2a", "property_id": "p1", "property": { "id": "p1", "name": "Loft Canal Saint-Martin" },
    "platform": "airbnb", "reference": "HMX4K2P9QA", "status": "confirmed",
    "check_in": "2026-10-24", "check_out": "2026-10-28", "nights": 4, "arrival_time": "16:30", "departure_time": null,
    "guest": { "first_name": "Camille", "last_name": "Laurent", "email": "camille@exemple.fr", "phone": "+33 6 12 34 56 78",
               "language": "fr", "country": "France", "count": 2 },
    "amounts": { "currency": "EUR", "guest_paid": 690.8, "payout": 566.15, "…": "…" },
    "created_at": "2026-10-22"
  }
}
  • data follows the API format (booking, job…), with the name of the property (property), the team member (member) or the guest (guest). Never any access code, Wi-Fi, deposit or police registration form.
  • Respond with a 2xx code within 8 seconds; redirects are not followed.
  • The same event can arrive twice (retry): id lets you ignore a duplicate. Delivery order isn’t guaranteed: created_at gives the order.
  • “Send a test”, in the app, sends a sample of the chosen event with "test": true and sample data: all the fields are there, so Zapier or Make can learn the shape of the data.

Verifying the signature

The X-OmniStay-Signature header is t=<horodatage>,v1=<signature> (horodatage: the timestamp). The signature is the HMAC-SHA256 (in hexadecimal) of <t>.<corps brut> (the raw body), calculated with the webhook secret (whsec_…, given at creation and visible in the app). Reject a timestamp older than 5 minutes.

import crypto from 'node:crypto';

// corps : le texte brut reçu, avant tout JSON.parse
function signatureValable(secret, entete, corps) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(entete || '');
  if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false;
  const attendue = crypto.createHmac('sha256', secret).update(`${m[1]}.${corps}`).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(attendue), Buffer.from(m[2]));
}

Retries and deactivation

  • Without a 2xx response: retry after 1 min, 5 min, 30 min, 2 h then 8 h (6 attempts in all), with exactly the same body and the same id.
  • 24 hours of consecutive failures: the webhook is deactivated. It can be reactivated in the app.
  • A 410 Gone response deactivates it immediately (REST Hooks model).
  • Revoking a key deactivates the webhooks it created. Delivery history is kept for 30 days.

Subscribing through the API

MethodEndpointEffect
POST/webhooksCreates a subscription: { "url": "https://…", "events": ["booking.created"], "name": "…" } (target_url and event are also accepted). Response 201 with data and secret, given only once by the API
GET/webhooks, /webhooks/{id}Subscriptions created with this key, and the list of events (events)
DELETE/webhooks/{id}Deletes a subscription created with this key
curl -X POST https://escale-roan.vercel.app/api/v1/webhooks \
  -H "Authorization: Bearer esk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://votre-outil.exemple.fr/omnistay", "events": ["booking.created", "booking.cancelled"] }'

A read-only key is enough. https:// URLs only (port 443), never an IP, local or internal address; at most 20 webhooks per company.

Zapier and Make

OmniStay has no official app in Zapier or Make: the connection goes through webhooks (to be notified) and the API key (to act). The steps are in the app, Settings › Integrations; the step-by-step guide, with three examples (bookings in Google Sheets, guest messages in Slack, a job created from a form), is in the help centre: “Relier OmniStay à Zapier” and “Relier OmniStay à Make” (in French).

Get notifiedAct in OmniStay
Zapier“Webhooks by Zapier” › “Catch Hook” (Zapier paid plans)“Webhooks by Zapier” › “Custom Request”: Method, URL, Data (JSON) and, in Headers, Authorization: Bearer esk_…
Make“Webhooks” › “Custom webhook”“HTTP” › “Make a request”: Authentication type “API key” (key Bearer esk_… in the Authorization header), body application/JSON

Owners and team

GET /owners
{ "data": [{ "id": "c1", "civility": "Mme", "first_name": "Sophie", "last_name": "Martin", "email": "sophie@exemple.fr",
             "phone": "06 12 34 56 78", "address": "8 rue Lepic, 75018 Paris", "commission": { "mode": "percent", "value": 20 },
             "since": "2023-04-02", "property_ids": ["p1", "p2"] }], "total": 1, "limit": 100, "offset": 0 }
GET /team
{ "data": [{ "id": "t1", "first_name": "Fatima", "last_name": "B.", "role": "cleaning", "status": "active",
             "property_ids": ["p1", "p2"] }], "total": 1, "limit": 100, "offset": 0 }

role is cleaning, keys, maintenance or other. Former team members don’t appear.

Lists and pagination

Lists return data, total, limit and offset. 100 items by default; limit goes up to 500. For the next page, increase offset: ?limit=100&offset=100. Bookings are sorted by check-in date, jobs by date and time.

Errors

In case of error, the response contains a stable code for your programs and a message in French:

{ "error": { "code": "read_only_key", "message": "Cette clé est en lecture seule : créez une clé avec le droit d’écriture." } }
StatusCodesMeaning
400invalid_date, invalid_period, invalid_status, invalid_type, invalid_limit, invalid_offset, invalid_jsonA filter or the request body is malformed
401missing_key, invalid_keyKey missing, unknown or revoked
403read_only_keyThe key doesn’t have write permission
404not_foundEndpoint or item not found
405method_not_allowedMethod not supported on this endpoint
422property_required, unknown_property, unknown_member, unknown_booking, invalid_time, invalid_duration, invalid_amount, invalid_textThe job to create is not valid
403, 404, 409, 422read_only, forbidden, unknown_action, not_found, conflict, invalid_input, invalid_state, ambiguous, already_exists…Actions: insufficient permissions, unknown action or item, item modified in the meantime (try again), parameters to correct, several possible items (be more specific), already done. The message says what to do.
409, 422url_required, invalid_url, events_required, already_exists, too_many_webhooksWebhooks: URL missing or refused (public https only), no known event, URL already subscribed, more than 20 webhooks
429rate_limitedMore than 120 calls in the minute: try again a little later
500, 503server_error, not_configuredProblem on our side: try again in a moment

Limits and security

  • A key gives access to your company’s data: keep it like a password. Use it from a server or an automation tool, never in a web page or a public app.
  • A key only sees its own company. It never gives access to access codes, Wi-Fi or payment methods; deposits can only be released or charged through the dedicated actions, logged in the journal.
  • Your guests’, owners’ and team members’ data remain your responsibility: only connect software you trust, and revoke a key as soon as it’s no longer in use.
  • 120 calls per minute per key, at most 20 active keys per company.
  • Version 1 endpoints won’t change. New features will come as new fields or new endpoints.

If you ask for help, give the name of the key used, never the key itself.

Ready in 5 minutes · no commitment

Behind every door, everything’s ready.

Cleaning, keys, deposits, owners: OmniStay prepares everything, even at night. €9.90 per listing per month, no commitment.

Create my account Try the demo

Compare OmniStay

  • vs Smoobu
  • vs Superhote
  • vs Guesty
  • vs Beds24
  • vs Hostaway
  • vs Lodgify
  • vs Hospitable
  • vs Smily
  • vs eviivo
  • vs Uplisting
  • vs Avantio
  • vs PassPass
  • vs Amenitiz
  • vs Rental Ninja
  • All comparisons

Software for short-term rental property managers and hosts, designed by a property manager.

bonjour@omnistay.ai

Our AI assistant answers you, 7 days a week.

Coming soon to theApp StoreComing soon toGoogle Play

The iPhone and Android apps are arriving in the coming weeks.

Features

Calendar and channel managerMessages and reviewsAI assistantCleaning and teamOwners and monthly invoicesGuest app and pre-check-inDeposits and paymentsInvoices and Factur-XAll features, A to Z

Integrations

Booking platformsiCal calendarsDynamic pricingCard paymentsSmart locksAccountingConnected AI (MCP) and APIZapier and MakeAll integrations

Who it’s for

Property managersIndividual hostsSwitch softwareComparisons

Resources

PricingTry the demoFrequently asked questionsBlogPractical guidesWhat’s newSystem statusAPI and MCP documentationReferrals: 30 to 50%About

Account

Create my accountLog inMy API keys (MCP)

Legal noticeTerms and conditionsPrivacyCookies

English
  • English
  • Español
  • Français
  • Português
  • Italiano
  • Deutsch
  • Ελληνικά

© 2026 OmniStay, designed by a property manager. Visits are counted anonymously (learn more); advertising cookies only with your consent (change your mind).

Airbnb, Booking.com, Expedia, Vrbo, Abritel, PriceLabs, Stripe, igloohome, Nuki, Tiime, Zapier and Make, and the other product and company names mentioned, are trademarks of their respective owners. Their mention indicates compatibility, an import option or a comparison: OmniStay is independent software, neither affiliated with, nor endorsed or sponsored by, these companies.