Docs

HTTP API: logs and traces

Request logs and traces, recorded errors, and the observability summaries behind the console's charts.

Updated Oct 18, 2026

Read the project's request logs and traces, and forward logs to your own tools. Guides: Logs and log drains, Request traces: why did this request fail?.

Base URLhttps://<project-ref>.sovarias.in — your project URL from Connect.
KeysSend the project's key as apikey. Calls made for a signed-in user also send Authorization: Bearer <access token>.
ErrorsA status code and {"detail": …} — a sentence, or {code, message} for errors your code may branch on (HTTP API).

Logs and request traces

GET/api/v1/observability/logs

The project's recent requests, newest first, one page at a time.

For a live tail, poll with after = the newest time you have; to load older ones pass before = the oldest. How far back depends on the plan (Logs and log drains).

Who
The project team (not app users or the anon key).

Query parameters

limitintegeroptionaldefault 50
Rows per page (1–200).
1–200
servicestring | nulloptional
One service (rest, auth, storage, functions…).
0–32 characters
statusstring | nulloptional
2xx, 3xx, 4xx, 5xx or errors.
pattern `^(2xx|3xx|4xx|5xx|errors) HTTP API: logs and traces | Sovaria Docs
qstring | nulloptional
Text in the path or method.
0–200 characters
afternumber | nulloptional
Only newer than this Unix time (live tail).
beforenumber | nulloptional
Only older than this Unix time.
sourcestringoptionaldefault app
app (your app's traffic, default), console (the team's activity) or all.
pattern `^(app|console|all) HTTP API: logs and traces | Sovaria Docs

Returns

logs[].timenumber
Unix seconds.
has_moreboolean
Older rows exist: page with before.
retention_minutesinteger
How far back the plan keeps logs.

Responses

  • 200Success.
  • 401No valid session or key.
curl -s "$URL/api/v1/observability/logs?status=errors&limit=50" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
  "project_id": "f0c3e9a2-1b4d-4e7f-8a6c-2d9b5e3f1a07",
  "logs": [
    {
      "time": 1792396800.412,
      "method": "GET",
      "path": "/rest/v1/orders",
      "status": 403,
      "duration_ms": 12.4,
      "service": "rest",
      "source": "app"
    }
  ],
  "has_more": true,
  "retention_minutes": 1440
}

GET/api/v1/request-traces

Recent refused (4xx) and failed (5xx) requests, each with why.

The trace id is the W3C traceparent id the SDKs send, also returned as X-Request-ID on every response. Kept for the plan's obs.trace_days (Request traces: why did this request fail?).

Who
The project team (not app users or the anon key).

Query parameters

kindstringoptionaldefault all
denied, failed or all.
One of denied, failed, all
beforestring | nulloptional
Older than this time (paging).
0–40 characters
limitintegeroptionaldefault 50
How many (1–100).
1–100

Returns

explanation.verdictstring
denied, failed or allowed.
explanation.by, step, reason, hintstring
What decided, in which step, why, and what to do.

Responses

  • 200Success.
  • 401No valid session or key.
curl -s "$URL/api/v1/request-traces?kind=denied" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
  "traces": [
    {
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "occurred_at": "2026-10-18T10:40:00.412+00:00",
      "method": "GET",
      "path": "/rest/v1/orders",
      "final_status": 403,
      "duration_ms": 12,
      "actor_id": null,
      "env_id": "",
      "explanation": {
        "verdict": "denied",
        "by": "policy",
        "service": "gateway",
        "step": "policy",
        "status": 403,
        "reason": "No access policy allows sql:select on orders for visitors who aren't signed in.",
        "detail": "NO_POLICY_DEFINED",
        "hint": "Add a policy for orders, or sign the user in first."
      }
    }
  ],
  "days": 7
}

GET/api/v1/request-traces/{trace_id}

One request, hop by hop (gateway checks, engine, SQL), with the explanation.

Who
The project team (not app users or the anon key).

Path parameters

trace_idstringrequired
32 hex characters (dashes ignored).

Responses

  • 200Success.
  • 404No such trace in this project, or older than the plan keeps.
  • 403App users and the anon key can't read traces.
  • 401No valid session or key.
curl -s "$URL/api/v1/request-traces/4bf92f3577b34da6a3ce929d0e0e4736" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "occurred_at": "2026-10-18T10:40:00.412+00:00",
  "method": "GET",
  "path": "/rest/v1/orders",
  "final_status": 403,
  "duration_ms": 12,
  "actor_id": null,
  "env_id": "",
  "explanation": {
    "verdict": "denied",
    "by": "policy",
    "service": "gateway",
    "step": "policy",
    "status": 403,
    "reason": "No access policy allows sql:select on orders for visitors who aren't signed in.",
    "detail": "NO_POLICY_DEFINED",
    "hint": "Add a policy for orders, or sign the user in first."
  },
  "hops": [
    {
      "seq": 1,
      "service": "gateway",
      "hop_kind": "gateway_denied",
      "status_code": 403,
      "error_class": "PolicyDenied",
      "error_detail": "NO_POLICY_DEFINED",
      "duration_ms": 6,
      "at": "2026-10-18T10:40:00.420+00:00"
    }
  ]
}

Log drains

GET/api/v1/observability/drains

Log drains: where the project's request logs are forwarded.

Who
The project team (not app users or the anon key).

Returns

drains[].activeboolean
Running (the oldest enabled drains up to the plan's obs.log_drains run; the rest wait).
sent, failed, last_delivery_at, last_errormixed
Delivery stats.

Responses

  • 200Success.
  • 401No valid session or key.
curl -s "$URL/api/v1/observability/drains" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
  "drains": [
    {
      "id": "drn_3f9a1c0b7e2d4a6f",
      "name": "Datadog prod",
      "kind": "datadog",
      "config": {
        "site": "datadoghq.eu"
      },
      "has_secret": true,
      "enabled": true,
      "disabled_reason": null,
      "active": true,
      "created_at": 1792310000.0,
      "sent": 18234,
      "failed": 2,
      "last_delivery_at": 1792396800.4,
      "last_error": null
    }
  ],
  "limit": 1,
  "used": 1
}

POST/api/v1/observability/drains

Forward request logs to Datadog, Grafana Loki or any HTTPS endpoint.

HTTPS drains receive batches of JSON signed with X-Sovaria-Signature; the signing secret is in this answer only. The plan limits how many drains run (obs.log_drains) (Logs and log drains).

Who
A project owner or admin, or the service-role key.

Body

kindstringrequired
One of http, datadog, loki
namestringoptional
configobjectoptional
http: url, header_name; datadog: site (datadoghq.com, us3.datadoghq.com, us5.datadoghq.com, datadoghq.eu, ap1.datadoghq.com, ddog-gov.com); loki: url, username.
secretstringoptional
http: the auth header's value; datadog: the API key (required); loki: password or token. Stored encrypted.

Responses

  • 201Created.
  • 403Not an owner/admin.
  • 422Unknown kind, invalid URL, no Datadog site or key, or a bad header name.
  • 401No valid session or key.
curl -s -X POST "$URL/api/v1/observability/drains" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"kind": "http", "name": "Our collector", "config": {"url": "https://logs.acme.com/ingest", "header_name": "X-Api-Key"}, "secret": "<collector key>"}'
Response
{
  "id": "drn_7c2e…",
  "name": "Our collector",
  "kind": "http",
  "config": {
    "url": "https://logs.acme.com/ingest",
    "header_name": "X-Api-Key"
  },
  "has_secret": true,
  "enabled": true,
  "disabled_reason": null,
  "active": true,
  "created_at": 1792310000.0,
  "sent": 0,
  "failed": 0,
  "last_delivery_at": null,
  "last_error": null,
  "signing_secret": "whsec_…(shown once)"
}

PATCH/api/v1/observability/drains/{drain_id}

Rename, re-configure, change the secret, or pause a drain.

Who
A project owner or admin, or the service-role key.

Path parameters

drain_idstringrequired
The drain.

Body

namestring | nulloptional
Name.
0–80 characters
enabledboolean | nulloptional
On or off.
configobject | nulloptional
New settings.
secretstring | nulloptional
New secret.
0–4,000 characters

Responses

  • 200Success.
  • 404No such drain.
  • 422Invalid settings.
  • 401No valid session or key.
curl -s -X PATCH "$URL/api/v1/observability/drains/drn_3f9a1c0b7e2d4a6f" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"enabled": false}'
Response
{
  "id": "drn_3f9a1c0b7e2d4a6f",
  "name": "Datadog prod",
  "kind": "datadog",
  "config": {
    "site": "datadoghq.eu"
  },
  "has_secret": true,
  "enabled": false,
  "disabled_reason": null,
  "active": false,
  "created_at": 1792310000.0,
  "sent": 18234,
  "failed": 2,
  "last_delivery_at": 1792396800.4,
  "last_error": null
}

DELETE/api/v1/observability/drains/{drain_id}

Delete a drain.

Who
A project owner or admin, or the service-role key.

Path parameters

drain_idstringrequired
The drain.

Responses

  • 200Success.
  • 401No valid session or key.
curl -s -X DELETE "$URL/api/v1/observability/drains/drn_3f9a1c0b7e2d4a6f" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
  "deleted": "drn_3f9a1c0b7e2d4a6f"
}

POST/api/v1/observability/drains/{drain_id}/test

Send a test batch to a drain now.

Who
A project owner or admin, or the service-role key.

Path parameters

drain_idstringrequired
The drain.

Responses

  • 200Success.
  • 401No valid session or key.
curl -s -X POST "$URL/api/v1/observability/drains/drn_3f9a1c0b7e2d4a6f/test" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
Response
{
  "ok": true,
  "error": null
}
Something unclear or missing on this page?Tell us