Skip to content

Calling functions

POST /api/functions/{area}/{name}/invoke
X-Tenant-Api-Key: stayfn_… required unless the Development dev tenant is enabled (scope functions:invoke)
X-Hotel-Id: <HOTEL> hotel the call runs in; omitted = the tenant's default hotel
Idempotency-Key: <key> required for functions with IdempotencyMode.KeyRequired
X-Correlation-Id: <id> optional; generated when absent, forwarded to OHIP as x-request-id
Content-Type: application/json body = the function's input record in camelCase, at most 1 MB
Response Meaning
200 + JSON the function’s output. X-Invocation-Id is always set. X-Idempotent-Replay: true means a stored result was returned.
204 the function returns no value
400 input failed the JSON schema or FunctionInputException
401 / 403 missing, unknown or revoked key, missing scope (missing_scope), suspended tenant
404 unknown function, or ResourceNotFoundException from OHIP
413 body over 1 MB
429 tenant quota (quota_exceeded) or OHIP budget not available in time, with Retry-After
503 host overloaded (overloaded, Retry-After: 1)
5xx OHIP or function failure after retries. The invocation is dead-lettered and can be replayed.

All errors are RFC 9457 problem documents that carry the correlation id. GET /api/functions/{area}/{name} returns a function’s descriptor with its input and output JSON schemas, and GET /api/catalog lists everything a key can see.

/api/openapi.json documents one operation per TenantApi/Public function (POST /api/functions/rsv/get-reservation/invoke, operationId rsv_getReservation) with its schemas, headers and problem responses, so any OpenAPI generator (Kiota, NSwag, openapi-generator, openapi-python-client) can produce a client. stayfn sdk generate writes a smaller, StayFn-aware SDK into your own repository from a host’s catalog (a key with functions:read) or from local function assemblies:

Terminal window
stayfn sdk generate --lang csharp --from https://stayfn.example.com --api-key "$STAYFN_API_KEY" --namespace Contoso.Ohip --out src/Contoso.Ohip
stayfn sdk generate --lang typescript --from https://stayfn.example.com --package-name @contoso/stayfn --out packages/stayfn
// C#: .NET 8, add a reference to the StayFn.Client package (released with the image as a .nupkg).
using var stayfn = new StayFnClient(new Uri("https://stayfn.example.com"), apiKey: "stayfn_…", defaultHotel: "HOTEL1");
var reservation = await stayfn.Rsv.GetReservationAsync("123456"); // flattened overload of GetReservationInput
await stayfn.MyArea.CreateBookingAsync(input, idempotencyKey: requestId); // methods of KeyRequired functions ask for the key
var response = await stayfn.Rsv.GetReservationWithResponseAsync(new() { ConfirmationNumber = "123456" });
Console.WriteLine(response.InvocationId);
// TypeScript: Node 18+, an ES module with no dependencies.
const stayfn = new StayFnClient({ baseUrl, apiKey, hotel: 'HOTEL1' });
const reservation = await stayfn.rsv.getReservation({ confirmationNumber: '123456' });

The SDKs send the key, hotel, correlation and idempotency headers, raise problems as StayFnProblemException / StayFnProblemError (Code, Status, CorrelationId, InvocationId, RetryAfter), retry a 429/503 with Retry-After at most twice, and return the invocation id and replay flag from the …WithResponse methods. Regenerate after the catalog changes; never edit the generated files.