HabeoDevelopers

Developer platform · updated May 25, 2026

The institutional ledger, programmable.

A versioned REST API, an OpenAPI 3.1 schema, signed webhooks, and OAuth Slack and Teams apps — all reading from the same higher-ed-grounded source of truth your auditors, finance team, and CISO already trust.

v1
REST · stable
OpenAPI 3.1
Codegen-ready
4
Webhook channels
JWT
Bearer auth
What we expose

Four developer surfaces. One source of truth.

Public REST API

/api/v1 · OpenAPI 3.1

Read assets, people, sites, and the caller's session. Cursor-paginated, bearer-authed, tenant-scoped server-side.

Signed webhooks

/api/webhooks/*

Outbound events for assets, tickets, MDM and Stripe. HMAC-signed, replay-protected, idempotent by event id.

Slack & Teams apps

OAuth · Bot Framework v4

Native Habeo Copilot apps for Slack and Microsoft Teams — installed by your workspace admin, not your engineering team.

Punchout receiver

/api/punchout/return

cXML 1.2.014 PunchOutOrderMessage receiver for procurement integrations (CDW, Connection, SHI, etc.).

Quick start · five lines of curl

From zero to your first row.

Get a Clerk session token, point curl at /api/v1/me, and you're in.

Step 01

Get a bearer token

Sign into Habeo, then mint a session token from /settings/api (or use the same Clerk JWT the mobile app uses).

# In a signed-in browser console
const t = await window.Clerk.session.getToken()
console.log(t)
Step 02

Resolve your session

Confirm the token works and inspect your caller, organization, and role.

curl https://www.usehabeo.com/api/v1/me \
  -H "Authorization: Bearer $HABEO_TOKEN"
Step 03

List a page of assets

Cursor-paginated. Pass meta.nextCursor back as ?cursor=… to walk the rest.

curl "https://www.usehabeo.com/api/v1/assets?limit=25" \
  -H "Authorization: Bearer $HABEO_TOKEN"
Open the full Swagger reference
Endpoint catalogue

Reads you can call. Receivers we listen on.

Mutating the ledger from third-party code is reserved for write-aware integrations (MDM sync, ITSM bridges, punchout). New write endpoints land here when the audit posture is ready.

Read endpoints
Bearer JWT required
  • GET /api/v1/meCaller, organization, and active role.
  • GET /api/v1/assetsPaged asset list — search by tag or serial.
  • GET /api/v1/assets/:idFull asset detail with assignment + location.
  • GET /api/v1/peoplePaged person directory from your HR source.
  • GET /api/v1/sitesTop-level locations (campuses, datacenters, leased facilities).
  • GET /api/v1/scan/:tagResolve an asset by its scanned tag (mobile).
  • POST /api/v1/push/registerRegister an Expo push token for mobile notifications.
Receivers
Signed · idempotent · audit-logged
  • POST /api/punchout/returncXML PunchOutOrderMessage receiver — procurement integrations.
  • POST /api/webhooks/clerkInbound auth events (user.created, organization.deleted, …).
  • POST /api/webhooks/itsm/:provider/:connectionIdInbound from ServiceNow, Freshservice, Jira SM.
  • POST /api/webhooks/mdm-loginInbound from Jamf, Intune, Kandji on enrollment.
  • POST /api/webhooks/stripeInbound billing events for the seat-licence meter.
Webhooks

Signed in, signed out, idempotent by id.

Every webhook payload carries an HMAC signature and a stable event id so your handler can verify provenance and dedupe replays.

The contract

  • HTTPS POSTJSON body, UTF-8.
  • X-Habeo-SignatureHMAC-SHA256 of the raw body using your endpoint secret.
  • X-Habeo-Event-IdStable UUID — dedupe on this if you see a retry.
  • X-Habeo-Delivery-AttemptInteger; 1 on first delivery, increments on retry.
  • Retry policyExponential backoff up to 24h on any non-2xx response.

Verifying a signature

import { createHmac, timingSafeEqual } from "node:crypto";

export function verify(rawBody: string, sig: string, secret: string) {
  const mac = createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(mac);
  const b = Buffer.from(sig);
  return a.length === b.length && timingSafeEqual(a, b);
}

Endpoint secrets are generated from /admin/integrations and rotated without downtime via the two-secret window.

For your security review

An API your CISO will sign off on.

Higher-ed IT lives or dies by the audit trail. The Habeo API was built to be auditable on day one — not retrofitted with logging when the first SOC 2 came around.

Same audit log as the UI.

Every API write and confirmed webhook delivery lands in the same immutable ledger that backs the in-product audit page. One place to look for SOC 2 and HECVAT review.

Tenant-scoped at the row level.

Tenancy is enforced server-side, not by your client. A token for org A cannot read org B's rows even if you guess the id.

College-unit RBAC, on the API.

The same unit scope that gates the UI gates the API. A Westmark-scoped token only ever sees Westmark rows — including from /api/v1/assets.

Clerk-issued JWTs.

No long-lived plaintext keys. Tokens are Clerk session JWTs (the same the mobile app uses) — revocable, rotatable, and bound to a real user.

OpenAPI 3.1, codegen-ready.

/api/v1/openapi.json is the source of truth — pull it into openapi-typescript, openapi-generator, Postman, or whatever your team already uses.

Stable v1 contract.

v1 is frozen and additive-only. Breaking changes ship under /api/v2 and run alongside v1 for at least 12 months.

Frequently asked

Developers, answered.

The questions we hear from every integration team in the first week. Answered briefly, with the technical detail your platform engineer will ask for next.

How do I authenticate?
Every request to /api/v1 carries an Authorization: Bearer <jwt> header. The token is a Clerk session JWT — the same one the Habeo mobile app uses. Mint one from /settings/api or via window.Clerk.session.getToken() in a signed-in browser. Tokens are short-lived; refresh through the Clerk client SDK.
Is there a sandbox?
Yes. Every paid plan includes a sandbox organization with synthetic-but-realistic higher-ed data (the same seed used for /demo). Sandbox tokens are interchangeable with production tokens — just point at the sandbox subdomain assigned to your account.
What's the rate limit?
100 requests per minute per token by default, with bursts to 200. Limits are returned on every response via the standard X-RateLimit-Limit / X-RateLimit-Remaining / X-RateLimit-Reset headers. Need more? Talk to us — higher limits are a config flag, not a contract amendment.
Do you have client SDKs?
We publish the OpenAPI 3.1 schema at /api/v1/openapi.json and recommend generating the client your team prefers (openapi-typescript for TS, openapi-generator for everything else). A first-party TS SDK is on the roadmap for late 2026.
How do webhook secrets work?
Each endpoint has its own secret, generated from /admin/integrations. Payloads are HMAC-SHA256 signed over the raw request body and the signature is sent in X-Habeo-Signature. Secrets rotate with a two-secret window so you can update your verifier without dropping deliveries.
Can I write to the ledger via the API?
Today the public API is read-only, with write surfaces reserved for the in-product Copilot (confirmation-flow gated) and write-aware integrations (MDM sync, ITSM bridges, cXML punchout). General-purpose write endpoints will land under /api/v1 once the audit posture matches the read surface.
Build on the ledger

Pull the schema. Ship the integration.

OpenAPI 3.1 at /api/v1/openapi.json, interactive reference at /api/v1/docs. Bring questions to the demo and we'll wire your sandbox up live.