One JSON over the institutional ledger.
Cursor-paginated reads over assets, people, and sites. Bearer-auth on every request. College-unit RBAC and tenancy enforced server-side — not in your client code, not in the prompt.
Everything you need on the back of a napkin.
Four nouns. One verb.
v1 is deliberately small. Every endpoint is a paginated GET; every response is a { data, meta } envelope.
Session
Resolve the caller behind the bearer token — user, organization, and active role. Use this to confirm the token works and gate which UIs you render.
Assets
The hardware and software lifecycle. Search by tag and serial, page through 25 at a time, fetch a single asset with assignment and location joins.
People
HR-sourced directory of staff, faculty, students, and contractors. Substring-matches on email, first name, last name. Mirrors what /people renders in the UI.
Sites
Top-level location hierarchy — campuses, datacenters, leased facilities, virtual sites. The first level beneath the organization.
What a v1 call looks like end-to-end.
Boring on purpose.
We picked one way to do each thing and stuck with it. Less surface to argue with, less surface to break.
Envelope shape.
Every successful response is { "data": ..., "meta": ... }. List endpoints return an array under data; detail endpoints return an object. meta is reserved for pagination and (rarely) a total count.
Cursor pagination.
Opaque base64url cursors — never positional offsets. Pass meta.nextCursor back as ?cursor= to walk the next page. Absent cursor means you've reached the end.
Search.
List endpoints accept ?q= for case-insensitive substring search across the most-asked-about columns (asset tag + serial, person email + name, site name + code). No DSL — keep it cheap.
Limit clamping.
?limit= accepts 1–100 with a default of 25. Out-of-range values are clamped, not rejected — the response header X-Habeo-Limit-Applied tells you what we used.
Dates and ids.
All timestamps are RFC 3339 / ISO 8601 in UTC with a trailing Z. All ids are RFC 4122 UUIDs unless otherwise noted (asset tags are free-form strings).
Tenancy.
Tenancy is enforced server-side via row-level security. There is no orgId query parameter; the bearer token resolves a tenant scope and the database refuses to return rows outside it.
One error envelope. Six codes that matter.
Every error response is { "error": { "code", "message", "details?" } }. Switch on error.code in your client — message is for humans.
100 req/min/token. Burst to 200.
The standard headers are on every response. Higher limits are a config flag — talk to us if you need them.
Total requests permitted in the current window.
Requests remaining before throttling kicks in.
Unix timestamp when the window resets.
Seconds to wait, only set on a 429.
A contract worth integrating against.
We don't break v1. The Habeo API is part of your audit posture; surprise renames are not on the table.
v1 is frozen.
Existing fields keep their names, types, and nullability for the lifetime of v1. Removing or renaming a field would be a breaking change and ships under /api/v2.
Additive is fair game.
We may add new optional fields, new endpoints, and new query parameters to v1 at any time. Your client should ignore unknown fields rather than fail closed.
12-month overlap.
When v2 ships, v1 runs alongside it for at least 12 months. Deprecation lives in the response Deprecation and Sunset headers before it lives in your inbox.
Changelog with each release.
Every v1 schema change is shipped through /api/v1/openapi.json with a build id and a human-readable changelog at /developers#changelog.
API, answered.
The questions that come up in every integration review. Answered briefly, with the detail your platform engineer will ask for next.
Why is v1 read-only?
Is there a sandbox tenant?
Do tokens expire?
Can I get a webhook instead of polling?
Do you support CORS?
How do I see what changed?
curl, schema, sandbox. Pick a starting point.
The Swagger UI is the fastest way to feel out the surface. The OpenAPI spec is the fastest way to wire up a generated client. The demo call is the fastest way to wire up your real data.