Getting started with the VerOps Public API

The VerOps Public API at api.verops.io: what it is, the /v1 base URL and versioning, creating an API-scoped key, the X-Api-Key header, your first curl call, rate limits, the JSON error model, timestamp formats, retries and idempotency, and the synchronous no-webhooks model.

public-apigetting-startedapi-keyauthenticationbase-urlversioningrate-limiterrorstimestampsretries

What the VerOps Public API is

The VerOps Public API is a stable, versioned HTTP API for programmatic access to your VerOps organization. Everything you can see in the product is scoped to your organization, and so is the API: a key only ever reads and writes your own organization's data. With it you can:

  • Send custom data in — your own metrics and events, stored alongside the rest of your telemetry.
  • Query that custom data back — raw samples, time-bucketed aggregates, or event searches.
  • Read your platform data out — metric names and values, logs, alerts, and software inventory — as JSON your scripts and integrations can consume.

Base URL and versioning

The API is served at:

https://api.verops.io

Every endpoint lives under the /v1 prefix, for example https://api.verops.io/v1/metrics/names. The /v1 segment is the API version. We add fields to responses without changing the version, but any breaking change ships under a new prefix (such as /v2) so your existing integrations keep working. No endpoints are deprecated today.

Get an API key with the API scope

Requests authenticate with an API key. Keys are created by an administrator under Settings -> API Keys. When you create the key, enable the API scope — that is the scope that grants Public API access.

A key looks like ta_live_xxxxxxxxxxxxxxxxxxxxxxxx. Copy it when it is shown; treat it like a password and store it in a secret manager, never in source control.

Warning: There are two scopes. API grants Public API access. Ingest is a separate scope used by agents to push telemetry and does not grant Public API access. A key that only has Ingest will be rejected with 403 forbidden. Make sure the API scope is enabled.

Send the key on every request

Pass the key in the X-Api-Key header, or as a Bearer token in the Authorization header — either is accepted:

# Preferred: X-Api-Key header
curl https://api.verops.io/v1/metrics/names \
  -H "X-Api-Key: ta_live_xxxxxxxxxxxxxxxxxxxxxxxx"

# Equivalent: Authorization: Bearer
curl https://api.verops.io/v1/metrics/names \
  -H "Authorization: Bearer ta_live_xxxxxxxxxxxxxxxxxxxxxxxx" 

Your first call

The health check needs no key and is the quickest way to confirm you can reach the API:

curl https://api.verops.io/v1/health
# -> 200  {"status":"ok"}

Now make an authenticated call. This lists the metric names available to your organization:

export KEY=ta_live_xxxxxxxxxxxxxxxxxxxxxxxx

curl https://api.verops.io/v1/metrics/names \
  -H "X-Api-Key: $KEY"
# -> 200  {"data":["http_server_request_count","cpu_usage", ...]}

A 200 with a {"data": ...} body means your key works and has the API scope. A 401 means the key is missing or invalid; a 403 means the key is valid but lacks the API scope.

Timestamps

Every timestamp field in the API — ts, start, end, startTime, endTime — accepts either form, and you can mix them freely:

  • an epoch value in milliseconds as a number, for example 1700000000000;
  • an ISO-8601 string, for example "2023-11-14T22:13:20Z".

All results are returned in UTC. Timestamps in responses (the ts field on points and events) are always epoch milliseconds as integers.

Rate limits

Each key has a per-minute request limit — a generous default, or a custom value set when the key is created. If you exceed it, the API returns 429 with a Retry-After header giving the number of seconds to wait. Back off for that long and retry.

The error model

Any non-2xx response returns a JSON envelope with a machine-readable code and a human-readable message:

{
  "error": {
    "code": "bad_request",
    "message": "metricName is required"
  }
}
Code Status Meaning
bad_request 400 The request body or parameters are invalid.
unauthorized 401 The API key is missing or invalid.
forbidden 403 The key is valid but does not have the API scope.
not_found 404 The resource does not exist (for example an unknown alert id).
rate_limited 429 Per-minute rate limit exceeded. Includes a Retry-After header.
internal_error 500 An unexpected error on our side. Safe to retry with backoff.
unavailable 503 The service is temporarily unavailable. Safe to retry with backoff.

Retries and idempotency

Read endpoints (every GET, and the query endpoints) are safe to retry freely. The send endpoints (POST /v1/custom/metrics and POST /v1/custom/events) are append-only and not idempotent — if a call succeeds on the server but the response is lost to a network error, retrying may record the sample or event a second time. For most metrics and events that duplication is harmless, but design with it in mind.

Recommended retry policy:

  • Retry on 429 (after waiting Retry-After seconds) and on 500 / 503, using exponential backoff.
  • Do not retry on 400, 401, or 403 — those will fail again until you fix the request or the key.

No webhooks or callbacks

The API is entirely synchronous request and response. There are no webhooks, no async callbacks, and no long-polling. To learn about new data you poll the read endpoints on your own schedule.

Interactive reference

Two machine-readable specifications and an interactive explorer are available:

Resource URL
Interactive reference (custom-data endpoints) https://api.verops.io/v1/docs
OpenAPI spec (custom-data endpoints) https://api.verops.io/v1/openapi.json
OpenAPI spec (platform-read endpoints) https://api.verops.io/openapi.json
Tip: Set your key once as an environment variable (export KEY=ta_live_...) and reference it as $KEY in every example on this page, so you never paste a secret into a command you might share.