API reference
The Telmoni read-only API: authentication, rate limits, and the public /v1 routes.
The Telmoni API is a read-only HTTP interface under /v1. Authenticated by a
project API key, it provides programmatic access to
organization metadata and roster details. It has no write routes; spans go to a
lane of their own, /otlp/v1/traces, with a key holding the
ingest scope, where the routes here need read. The routes are also described
as an OpenAPI 3.1 document,
contract/openapi.json
in the platform's repository, generated from the same table the server routes by.
Base URL and authentication
https://api.telmoni.com/v1(On a self-hosted instance, replace https://api.telmoni.com with your
deployment's own machine host, or with its console's host where the machine
lanes are routed by path: Self-hosting → Production.)
Authenticate all requests by including your project API key as a bearer token:
Authorization: Bearer telmoni_...Requests lacking a valid or live key return 401 Unauthorized, as a problem
document; a revoked, expired or unknown key, or one whose organization is
being deleted, answers the same way:
{
"type": "/errors/auth/invalid-token",
"title": "invalid token",
"status": 401,
"detail": "a live telmoni_ API key is required"
}A live key without the read scope is refused with 403 Forbidden and
/errors/authz/forbidden (API keys).
HTTP methods
All routes accept GET and HEAD. Any other method returns 405 Method Not Allowed with an Allow header and a problem document, except OPTIONS, which
answers 204 with Allow: GET, HEAD, OPTIONS.
Rate limits
| Scope | Limit |
|---|---|
| Per API key | 600 requests / minute |
| Per source IP address (an IPv6 address by its /64) | 1,200 requests / minute |
Exceeding either rate limit returns 429 Too Many Requests along with a
Retry-After header. See Errors. The server meters both
itself, the address read past the proxies in front of it
(TRUSTED_PROXY_HOPS), and shares the counts between its replicas through
Redis.
GET /v1/organization
Retrieves the organization associated with the presented token.
Response
200 OK application/json
{
"organization_id": "org_019a0b8c3f2e7d41",
"slug": "acme-corp",
"name": "Acme Corp",
"owner": {
"email": "you@example.com",
"display_name": "Sam Rivera"
}
}organization_id: The unique, immutable identifier of the organization.slug: The first segment of the organization's console URLs (/acme-corp). It changes only when the organization's URL is changed in its Settings (see Name and URL);organization_idnever does.name: The organization's name.owner: The organization Owner'semailanddisplay_name(nullwhen they have not set one).owneritself isnullif the organization has no owner on record.
GET /v1/members
Returns the roster of the project the key was minted on: the organization's Owner first, then the project's members by join date, newest first. It is the same list the project's Members page shows, and never the organization's roster, which a project Admin cannot see in the console either.
Response
200 OK application/json
{
"members": [
{
"id": "019a0b8c-3f2e-7d41-9c5a-6e2b1f0d8a47",
"member_id": "user_7Hq3kZ2mN8vLp4Xs",
"email": "you@example.com",
"display_name": "Sam Rivera",
"role": "owner",
"created_at": "2026-08-28T12:00:00Z",
"is_owner": true,
"transfer_offer_expires_at": null
},
{
"id": "019a3d52-7b10-7c9e-a4f1-2d8e6b0c9a13",
"member_id": "user_2bR9tC5wQ1yJm6Fd",
"email": "alex@example.com",
"display_name": null,
"role": "admin",
"created_at": "2026-09-01T09:30:00Z",
"is_owner": false,
"transfer_offer_expires_at": null
}
]
}id: Unique identifier of the membership record.member_id: The person's user ID,user_and 16 characters, minted at their first sign-in whichever way they signed in.email: Member's email address.display_name: User's display name, ornull.role: The seat's role on the project (adminormember), orowneron the organization Owner's row. An organization Admin's standing on every project comes from the organization, not from a seat, so one appears here only with a seat of their own, under that seat's role.created_at: ISO-8601 UTC timestamp of when the member took their seat; on the Owner's row, when the project was created.is_owner: Boolean flag indicating if this member is the organization Owner.transfer_offer_expires_at: UTC timestamp indicating when an open offer to hand the project to this admin expires, ornullif none is pending.
Errors
Every error response is an RFC 9457 problem document
(application/problem+json) with a structured error type. A 401 carries a
WWW-Authenticate: Bearer header, and a 429 or a feature-off 503 a
Retry-After header. Full details and status codes are cataloged in
Errors, including the two the server's door answers for a method
or a path no lane takes.
If the API is switched off for your organization or the deployment, requests
respond with 503 Service Unavailable and the /errors/tenant/feature-off
problem type. A 503 with /errors/auth/identity-unavailable, and no
Retry-After, means Telmoni could not read the key or the API's switch just
then: retry, and don't take the key for revoked.
Field inventory
Every attribute Telmoni reads from a span, at the pinned commit of the GenAI semantic conventions: where it is read, what becomes of it, and the content mode it needs. Anything else is dropped at the door.
Errors
How Telmoni reports errors on the API and in the console: problem documents (RFC 9457), error types, status codes, and the two the machine host's door mints.