Skip to content

Manifest reference

Every app is defined by its manifest — a JSON document you edit through the Developer panel. The manifest declares what your app does, what data it needs access to, and which optional surfaces it enables. Stayblox validates the manifest on every save and again at version submission.

Complete example

jsonc
{
  "name": "Smart Lock Manager",
  "description": "Automatically deliver access codes to guests at check-in.",

  // Access scopes the host consents to at install.
  "scopes": ["read_bookings", "read_contacts", "write_conversations"],

  // Webhook topics to receive (must be covered by scopes).
  "webhooks": {
    "topics": ["booking.confirmed", "booking.cancelled", "booking.checked_in"]
  },

  // App-owned data fields on bookings, properties or contacts.
  "metafields": [
    {
      "owner": "booking",
      "key": "access_code",
      "type": "string",
      "visibility": "guest"        // exposed to guests in emails + themes
    },
    {
      "owner": "booking",
      "key": "lock_battery_pct",
      "type": "number",
      "visibility": "host"         // shown in the host panel "App data" section
    }
  ],

  // Per-install settings the host fills in during installation.
  "settings_schema": [
    { "key": "api_key", "type": "string", "label": "Lock API key", "required": true },
    { "key": "default_code_length", "type": "number", "label": "Code length", "default": 6 }
  ],

  // Embedded UI page rendered inside the host panel.
  "app_page": {
    "url": "https://app.smartlock.example/stayblox"
  },

  // OAuth redirect URIs for the "Connect your Stayblox account" flow.
  "oauth": {
    "redirect_uris": ["https://smartlock.example/auth/stayblox/callback"]
  },

  // HTML snippets injected into storefront slots.
  "injections": [
    {
      "slot": "head",
      "template": "<script src=\"https://cdn.smartlock.example/widget.js?key={{ api_key }}\"></script>"
    }
  ]
}

Keys

name

RequiredType
Yesstring

The display name shown to hosts in the marketplace and panel.


description

RequiredType
Nostring

A short description of what your app does, shown in the marketplace listing.


scopes

RequiredType
Noarray of scope strings

Access scopes the host consents to when installing. Stayblox checks the install's granted scopes on every API call and webhook delivery — not the manifest directly. See Scopes for the full catalog.

jsonc
"scopes": ["read_bookings", "read_contacts", "write_conversations"]

Validation: every entry must be a known AppScope value; unknown strings are rejected. A webhook topic also requires its scope to be listed here.


webhooks

RequiredType
Noobject

Topics you want delivered to the install's webhook endpoint.

jsonc
"webhooks": {
  "topics": ["booking.confirmed", "booking.cancelled"]
}

Validation: every topic must be a known WebhookTopic value, and its required scope must appear in scopes. See Webhooks for the full topic list.


metafields

RequiredType
Noarray of objects

Declares app-owned data fields you intend to store on bookings, properties, or contacts. See Metafields for how to write and read these at runtime.

Each entry:

PropertyRequiredValuesDescription
ownerYesbooking | property | contactThe model this field attaches to.
keyYes^[a-z0-9_]{1,64}$Unique identifier for this field (snake_case, max 64 chars).
typeYesstring | number | boolean | dateThe value's data type. Stored as text; the type is advisory for display.
visibilityYesprivate | host | guestWho sees the value (see below).

Visibility:

ValueWho sees it
privateOnly your app via the API. Never shown in the host panel or guest emails.
hostShown in the "App data" section on booking/property detail pages in the host panel.
guestLike host, plus exposed as variables in guest email templates and in the app_data(booking) Twig function for themes.

Validation: owner must be booking, property, or contact; key must match ^[a-z0-9_]{1,64}$; type must be one of the four values above; visibility must be one of the three values above.


settings_schema

RequiredType
Noarray of objects

Defines the per-install settings form shown to the host during installation and on the app's settings page. Values are stored on the install and passed to your server in session payloads (payment/channel protocols) and accessible via the settings object on the install's token context.

Each entry:

PropertyRequiredDescription
keyYesstring. Identifier for this setting.
typeYesstring, number, boolean, or select.
labelYesHuman-readable label shown in the form.
requiredNoboolean. Defaults to false.
defaultNoDefault value shown pre-filled.
optionsFor selectArray of { value, label } objects.

The setting value is available in injections templates as (see below) and in session payloads under settings.key.


injections

RequiredType
Noarray of objects

HTML snippets rendered into named slots in the storefront. Each entry defines where the snippet goes and what to render. See Injections for the full guide including slot names and template examples.

jsonc
"injections": [
  {
    "slot": "head",
    "template": "<script src=\"https://cdn.example.com/widget.js?key={{ api_key }}\"></script>"
  }
]

Each entry:

PropertyRequiredDescription
slotYesThe named storefront slot (e.g. head, body_end).
templateYesRaw HTML. May contain placeholders interpolated from the install's settings at render time.

Sanitization: injection templates are reviewed and sanitized as part of the app review process. Scripts must load from a fixed https:// origin; inline javascript: URIs and <script> blocks without a src are rejected.


app_page

RequiredType
Noobject

Declares an embedded UI page rendered inside the host panel as a sandboxed iframe. See Embedded pages for the full JWT session and token-refresh protocol.

jsonc
"app_page": {
  "url": "https://app.example.com/stayblox"
}
PropertyRequiredDescription
urlYesThe https:// URL of your app page. The iframe loads {url}?session=<JWT>.

Validation: must be a valid https:// URL.


oauth

RequiredType
Noobject

Registers redirect URIs for the OAuth 2.0 authorization-code install flow. See OAuth install for the complete flow.

jsonc
"oauth": {
  "redirect_uris": [
    "https://app.example.com/auth/stayblox/callback"
  ]
}
PropertyRequiredDescription
redirect_urisYesArray of https:// URIs. The redirect_uri parameter in an authorize request must exactly match one of these strings (no wildcards, no partial matches).

Restriction: OAuth install is available for free and externally-billed apps only. Paid platform-billed apps install through the marketplace.

Validation: every URI must be a valid https:// URL.


payments

RequiredType
Required for type: paymentobject

Payment-protocol specifics: endpoints, capabilities, and currency support. See Payment apps for the full reference.


channel

RequiredType
Required for type: channelobject

Channel-protocol specifics: ARI endpoints, supported OTA identifiers. See Channel managers for the full reference.


Validation rules summary

RuleDetail
Scope stringsMust be known AppScope values.
Webhook topicsMust be known WebhookTopic values; required scope must be listed.
All URLsMust be valid https:// URLs (no http://, no IP addresses without explicit approval).
oauth.redirect_urisExact-match strings — no wildcards, no trailing slashes unless registered with one.
Metafield ownersMust be booking, property, or contact.
Metafield keysMust match ^[a-z0-9_]{1,64}$.
Metafield typesMust be string, number, boolean, or date.
Injection slotsMust be known storefront slot names.
Injection templatesSanitized at review — only trusted https:// script/resource origins allowed.
Settings schemaEach entry must declare a string key and a string type.

Validation runs on every partner save (showing errors inline) and again at version submission. Submitting with validation errors is blocked.

© Stayblox — Developer Platform