Skip to content

CI ingest API overview

One pattern for any CI — POST your failed-build log to Exlogare with an API key and get an RCA in the dashboard (and on paid plans, in Slack/Telegram/Matrix).

The universal CI ingest API is how a build server tells Exlogare “this run failed, here’s the log — do your thing”. It works with any CI/CD platform: Jenkins, CircleCI, TeamCity, Drone, Woodpecker, GitHub Actions, GitLab CI, Buildkite, AppVeyor, custom in-house tooling.

TL;DR

  1. Create an API token in Settings → API tokens with the ingest scope.
  2. Add a “on failure” step to your CI that curls the log to the right /api/ingest/* endpoint.
  3. Open the Analyses page in the dashboard — your RCA shows up there with a “via API ingest” badge.

If you do not want to assemble JSON by hand, use the Exlogare CLI. It calls the same ingest API:

exl ingest --provider generic --project myorg/web --status failed --log-file build.log

Available on Free

API ingest is available on every plan, including Free. Free is capped at:

  • 3 active API tokens at a time;
  • 20 lifetime analyses;
  • dashboard-only delivery (no Slack/Telegram/Matrix fan-out — that starts on Startup).

Authentication

Send the token as a bearer credential:

curl -H "Authorization: Bearer $EXLOGARE_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{ ... }' \
     https://api.exlogare.net/api/ingest/<provider>

Tokens look like exl_… and are displayed only once when created. Copy the raw secret into your CI’s secret store immediately.

In CI, the CLI reads the same token from EXLOGARE_TOKEN, so your secret-store setup stays the same:

EXLOGARE_TOKEN=exl_... exl ingest --provider generic --project myorg/web --log-file build.log

Pick the right endpoint

EndpointUse it for
POST /api/ingest/jenkinsJenkins (declarative, scripted, freestyle)
POST /api/ingest/circleciCircleCI Cloud or Server
POST /api/ingest/teamcityTeamCity (Cloud or self-hosted)
POST /api/ingest/droneDrone CI / Woodpecker
POST /api/ingest/logGeneric — Buildkite, AppVeyor, custom CI, GitHub Actions without OAuth, GitLab CI without OAuth

Each endpoint accepts a JSON body with the provider’s native field names (workflow id / build id / build number) plus the failed-step log.

Limits and behaviour

  • Body size: up to 10 MiB per request. Larger payloads return 413.
  • Rate limit: 60 req/min per tenant by default. Past that you get 429.
  • Quota: each ingested analysis counts against your monthly / lifetime quota. Quota exhausted returns 403 with {"status":"quota_exhausted"}.
  • Idempotency: repeated POSTs for the same (provider, run_id, job_id) return the same analysis_id — safe to retry from a failing CI step.
  • Logs are not stored: the raw log is processed in memory to produce an RCA and discarded. Only the generated RCA and routing metadata (run id, branch, commit, URL) are persisted.

Example response

Every ingest endpoint returns the same shape:

{ "status": "accepted", "analysis_id": "39af2c01-..." }

Use the analysis_id to deep-link the customer to /dashboard/analyses/<id> from your CI’s notification message.

What about webhook signatures?

The API token is the auth surface. We don’t require an additional HMAC signature on top — adding one would be double-locking without a real threat model improvement. Rotate the token if you suspect a leak.