Code examples and SDKs
The same core operations (send a metric, query it back, read alerts) shown in cURL, Python (requests), and JavaScript (fetch), plus a retry helper. There is no official SDK yet, but the OpenAPI specs at /v1/openapi.json and /openapi.json generate one with openapi-generator.
Three core operations, three languages
The same three operations — send a metric, query it back, and read platform alerts — shown in cURL, Python, and JavaScript. In every example the API key comes from an environment variable named VEROPS_API_KEY; never hard-code a key.
cURL
export VEROPS_API_KEY=ta_live_xxxxxxxxxxxxxxxxxxxxxxxx
BASE=https://api.verops.io
# 1. Send a metric
curl -X POST "$BASE/v1/custom/metrics" \
-H "X-Api-Key: $VEROPS_API_KEY" -H "Content-Type: application/json" \
-d '{"metrics":[{"name":"orders.count","value":42,"labels":{"region":"us"}}]}'
# 2. Query it back (hourly sum)
curl -X POST "$BASE/v1/custom/metrics/query" \
-H "X-Api-Key: $VEROPS_API_KEY" -H "Content-Type: application/json" \
-d '{"metricName":"orders.count","start":1700000000000,
"end":1700604800000,"step":"1h","agg":"sum"}'
# 3. Read active alerts
curl "$BASE/v1/alerts?status=active&page=0&size=20" \
-H "X-Api-Key: $VEROPS_API_KEY"
Python (requests)
import os
import requests
BASE = "https://api.verops.io"
KEY = os.environ["VEROPS_API_KEY"]
session = requests.Session()
session.headers.update({"X-Api-Key": KEY})
def send_metric(name, value, labels=None):
body = {"metrics": [{"name": name, "value": value, "labels": labels or {}}]}
r = session.post(f"{BASE}/v1/custom/metrics", json=body, timeout=30)
r.raise_for_status() # 202 on success
return r.json()["accepted"]
def query_metric(name, start_ms, end_ms, step="1h", agg="sum"):
body = {"metricName": name, "start": start_ms, "end": end_ms,
"step": step, "agg": agg}
r = session.post(f"{BASE}/v1/custom/metrics/query", json=body, timeout=30)
r.raise_for_status()
return r.json()["points"]
def active_alerts(page=0, size=20):
r = session.get(f"{BASE}/v1/alerts",
params={"status": "active", "page": page, "size": size},
timeout=30)
r.raise_for_status()
return r.json()["data"] # list of alerts; paging is in ["meta"]
if __name__ == "__main__":
print("accepted:", send_metric("orders.count", 42, {"region": "us"}))
print("points:", query_metric("orders.count", 1700000000000, 1700604800000))
print("alerts:", active_alerts())
A small helper that respects Retry-After and backs off on 429 and 5xx:
import time
def post_with_retry(session, url, body, max_attempts=5):
for attempt in range(1, max_attempts + 1):
r = session.post(url, json=body, timeout=30)
if r.status_code < 300:
return r.json()
if r.status_code == 429 or r.status_code >= 500:
wait = int(r.headers.get("Retry-After", 2 ** attempt))
time.sleep(wait)
continue
r.raise_for_status() # 4xx other than 429: do not retry
raise RuntimeError("exhausted retries")
JavaScript (Node fetch)
Uses the built-in fetch available in modern Node and browsers.
const BASE = "https://api.verops.io";
const KEY = process.env.VEROPS_API_KEY;
const headers = { "X-Api-Key": KEY, "Content-Type": "application/json" };
async function sendMetric(name, value, labels = {}) {
const res = await fetch(`${BASE}/v1/custom/metrics`, {
method: "POST",
headers,
body: JSON.stringify({ metrics: [{ name, value, labels }] }),
});
if (!res.ok) throw new Error(`send failed: ${res.status}`);
return (await res.json()).accepted; // 202
}
async function queryMetric(name, startMs, endMs, step = "1h", agg = "sum") {
const res = await fetch(`${BASE}/v1/custom/metrics/query`, {
method: "POST",
headers,
body: JSON.stringify({ metricName: name, start: startMs, end: endMs, step, agg }),
});
if (!res.ok) throw new Error(`query failed: ${res.status}`);
return (await res.json()).points;
}
async function activeAlerts(page = 0, size = 20) {
const url = `${BASE}/v1/alerts?status=active&page=${page}&size=${size}`;
const res = await fetch(url, { headers: { "X-Api-Key": KEY } });
if (!res.ok) throw new Error(`alerts failed: ${res.status}`);
return (await res.json()).data; // array of alerts; paging is in .meta
}
(async () => {
console.log("accepted:", await sendMetric("orders.count", 42, { region: "us" }));
console.log("points:", await queryMetric("orders.count", 1700000000000, 1700604800000));
console.log("alerts:", await activeAlerts());
})();
Is there an official SDK?
There is no official SDK yet. Because the API ships machine-readable OpenAPI specifications, you can generate a typed client in most languages today. Two specs are published:
| Spec | Covers |
|---|---|
https://api.verops.io/v1/openapi.json |
The custom-data endpoints (send and query). |
https://api.verops.io/openapi.json |
The platform-read endpoints (metrics, logs, alerts, inventory). |
Generate a client with openapi-generator:
# Python client from the custom-data spec
openapi-generator-cli generate \
-i https://api.verops.io/v1/openapi.json \
-g python -o ./verops-client-python
# TypeScript client from the platform-read spec
openapi-generator-cli generate \
-i https://api.verops.io/openapi.json \
-g typescript-fetch -o ./verops-client-ts
The interactive reference at https://api.verops.io/v1/docs lets you try the custom-data endpoints from the browser.
Best practice: Whatever language you use, centralize three things in one client wrapper: the base URL, the API key from an environment variable or secret manager, and the retry policy (honorRetry-After, back off on429and5xx, never retry400/401/403). Every call then inherits correct, consistent behavior.