Pulse API
The Pulse API has two sides. Telemetry senders write logs, traces and metrics with a project ingest key. People and services acting for a person read and manage everything else with their Orbit session. This page is for developers who send data or build on the results.
Pulse routes live under /api/v1/pulse/* and /otlp/* on your site’s address. For the conventions shared by all Orbit APIs, see API overview.
Authentication
Section titled “Authentication”| Caller | Credential | Allowed |
|---|---|---|
| A telemetry sender | Project ingest key in X-Pulse-Key: <key> or Authorization: Bearer <key> |
Intake only. The key decides the project, and any project named in the payload is ignored. |
| A person, or a service acting for them | The orbit_session cookie |
Reads and management. Pulse checks the person’s current project role on every request. |
| A Lumen agent In development | Authorization: Bearer oas_... |
A fixed list of read routes, as a viewer |
Every project role can read. Members write dashboards, monitors, SLOs and incidents and triage errors, and project administrators manage keys, quotas and rules. Errors are { "error": "..." }. A query syntax error adds position, the 0-based character index. OTLP endpoints answer errors with a google.rpc.Status body in the request’s encoding.
Personal API tokens (opt_...) and service-account tokens do not work on Pulse routes. Reading and managing need a signed-in Orbit session. A browser’s cross-origin writes are refused unless the origin is allowed. See API authentication.
Send telemetry
Section titled “Send telemetry”| Route | Body |
|---|---|
POST /otlp/v1/logs, /otlp/v1/traces, /otlp/v1/metrics |
OTLP protobuf or JSON, optionally gzip, deflate, zstd or br. See OpenTelemetry (OTLP). |
POST /api/v1/pulse/intake/logs |
One JSON object, an array of objects, or newline-delimited objects |
POST /api/v1/pulse/intake/metrics |
One JSON point, an array of points, or newline-delimited points |
curl -sS -X POST "https://acme.orbit.inortix.com/api/v1/pulse/intake/metrics" \ -H "X-Pulse-Key: $INGEST_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"queue.depth","type":"gauge","unit":"items","value":42,"service":"worker","env":"production","tags":["queue:emails"]}'JSON intake answers 202 with {"accepted": 1, "rejected": 0, "errors": []}, and 400 when nothing was accepted. A metric type is gauge, count or histogram, and JSON counts are deltas. Log fields are listed in Send your first logs.
Limits per request: at most 10,000 records and a body size set per key (default 5 MiB, at most 16 MiB). The decompressed size is at most 8 times that, capped at 64 MiB. A key also has a records-per-minute budget. A request over the budget answers 429 with Retry-After and stores nothing.
A daily quota keeps the records that fit and rejects the rest. OTLP answers 200 with the rejected count in partialSuccess, and JSON log intake answers 202 with rejected and the reason in quota. See Usage, retention and quotas.
Read and manage
Section titled “Read and manage”These routes sit under /api/v1/pulse/projects/{projectId}. They take q in the shared query syntax. They also take from and to as RFC 3339 or Unix milliseconds. The default range is the last 15 minutes, clamped to the project’s retention and to at most 32 days.
curl -sS -G "https://acme.orbit.inortix.com/api/v1/pulse/projects/<project id>/logs" \ --cookie "orbit_session=<session cookie>" \ --data-urlencode "q=service:checkout status:error" \ --data-urlencode "limit=20"The answer is {"logs": [...], "nextCursor", "from", "to"}, newest first. Pass nextCursor as cursor for the next page.
The session cookie acts as you with all your access. Keep it out of shared scripts and logs.
| Area | Main routes | Who writes |
|---|---|---|
| Logs | GET /logs, /logs/histogram, /logs/facets, /logs/export (CSV), /logs/tail (server-sent events) |
Saved views: members. Pipelines, exclusions and log-based metrics: administrators. |
| Traces | GET /spans, /traces/{traceId}, /apm/services, /apm/map |
Trace retention: administrators |
| Metrics | GET /metrics, POST or GET /metrics/query |
None, read only |
| Errors | GET /errors, /errors/{groupId}, PATCH /errors/{groupId} |
Members triage. Fingerprint rules: administrators. |
| Monitors | GET or POST /monitors, /monitors/validate, /monitors/preview, /alerts, /downtimes, /webhooks |
Members. Webhooks: administrators. |
| Dashboards | GET or POST /dashboards, /dashboards/{id}/export, POST /dashboards/import |
Members |
| SLOs | GET or POST /slos, /slos/validate |
Members |
| Incidents | GET or POST /incidents, /incidents/{id}/notes, /links, /tasks, PUT /postmortem |
Members. Delete: administrators. |
| Usage | GET /usage/today, GET /usage (days from 1 to 90) |
Quotas: administrators |
| Project | GET or POST /ingest-keys, GET or PATCH /settings |
Administrators |
Updates to monitors, dashboards, SLOs, incidents and error groups accept the version you read, and a stale one answers 409. POST /monitors/validate and /slos/validate check a definition and save nothing. GET /query/validate checks a query.
Creating a bug from an error group or an incident follow-up task does not write to Orbit directly. Pulse queues the request, and Orbit creates the work item as the requesting person with their permissions. See Errors and Orbit bugs.
Monitor webhooks
Section titled “Monitor webhooks”Monitor notifications can post to a webhook that you register. Each request carries X-Pulse-Event, X-Pulse-Delivery (the same on every retry, so you can drop duplicates) and X-Pulse-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<body>">. Check the signature and reject old t values. Any 2xx answer is a delivery, and other answers retry, 8 attempts in all. Pulse refuses loopback, private and link-local addresses. See Monitors and alerts.