Skip to main content

Developers

Build on the hotel back-office platform.

Innrly exposes secure REST APIs and webhooks for hotel data — invoices, GL, labor, reservations, and reconciliation. Built for portfolios, accounting partners, and integrators.

What's available

APIs, webhooks, and partner tooling.

REST API

Read-and-write access to properties, invoices, GL entries, labor records, and reconciliation results. OAuth 2 authentication.

Webhooks

Real-time events for invoice posted, reconciliation cleared, exception flagged, and payroll exported. Signed payloads, retries built in.

Partner integrations

Pre-built connectors to PMSs, accounting, payroll, and banking. Want to be in the catalog? Talk to us.

Documentation

API reference, webhook signatures, rate limits, and code samples — available to active accounts and partners.

Sample · Webhook payload

POST https://your-app.example.com/innrly
Content-Type: application/json
X-Innrly-Signature: t=1733191800,v1=ad34f8b1c2e9...

{
  "event": "invoice.posted",
  "id": "evt_01HXYZABC123",
  "created_at": "2026-06-08T14:22:11Z",
  "data": {
    "id": "inv_01HXYZ...",
    "property_id": "prop_chi_riv",
    "vendor": "Sysco",
    "total": 4821.55,
    "gl_account": "5101 - F&B Cost",
    "approved_by": "controller@portfolio.com",
    "posted_to": "quickbooks_online"
  }
}

Expected response

HTTP/1.1 200 OK
Content-Type: application/json

{ "received": true }

Respond with 2xx within 10 seconds. Non-2xx or timeouts trigger automatic retry with exponential backoff for up to 24 hours.

Verify the signature

import crypto from "crypto";

// Header format: t=<unix-ts>,v1=<hex-hmac>
// Signed payload: "<t>.<raw request body>"  using HMAC-SHA256
export function verifyInnrlySignature(
  header: string,
  rawBody: string,
  secret: string,
  toleranceSec = 300,
): boolean {
  const parts = Object.fromEntries(
    header.split(",").map((p) => p.split("=") as [string, string]),
  );
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");

  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(parts.v1 ?? "", "hex");
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Always verify against the raw request body — JSON-stringifying after parse will break the HMAC. Rotate webhook secrets from the partner dashboard; both old and new secrets verify for 24 hours after rotation.

Building on Innrly?

API access is provisioned per account and per partner. Tell us what you're building — we'll get you keys and documentation.

Try Innrly free for 90 days
Full platform · No credit card