audit_
api reference

The same pipeline, behind a REST API.

Base URL: https://audit-api.bjole.dev. Authentication is a header-borne API key per tenant. Read on.

quick reference

Five endpoints, no surprises.

POST/audits

Kick off a new audit. Returns 202 with the audit id.

GET/audits

List audits for the calling tenant.

GET/audits/:id

Single audit status + metadata (polling).

GET/audits/:id/events

Server-sent events stream — chunk events, done, error, ping.

GET/audits/:id/chunks/:name

Pull one chunk as JSON. Names: company, financial, technical, risks, recommendations, score, executive-summary, industry-analysis, validation.

Authentication

Every request needs an x-api-key header. SSE and chunk endpoints also accept ?api_key= as a query param so native EventSource works.

You get an API key when you sign up. Keys are tenant-scoped, are stored as a sha-256 hash on our side, and can be revoked from the dashboard. We log key prefix + last-used-at — never the raw key.

Create an audit

Returns immediately with 202 Accepted and an id. The audit runs in the background; subscribe to the SSE stream below to watch progress.

curlbash
curl -X POST https://audit-api.bjole.dev/audits \
  -H "x-api-key: $AUDIT_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "company": "Spotify",
    "industry": "Music Streaming",
    "location": "Sweden",
    "size": "9000+"
  }'

# 202 Accepted
# {
#   "id": "8b3f...c3ce",
#   "status": "queued",
#   "storage_prefix": "audit-runs/<tenant>/<audit-id>/",
#   "created_at": "2026-05-23T10:34:27Z"
# }
JavaScriptts
const res = await fetch("https://audit-api.bjole.dev/audits", {
  method: "POST",
  headers: {
    "x-api-key": process.env.AUDIT_API_KEY!,
    "content-type": "application/json",
  },
  body: JSON.stringify({
    company: "Spotify",
    industry: "Music Streaming",
    location: "Sweden",
    size: "9000+",
  }),
});

const { id } = await res.json();
Pythonpython
import os, requests

res = requests.post(
    f"https://audit-api.bjole.dev/audits",
    headers={"x-api-key": os.environ["AUDIT_API_KEY"]},
    json={
        "company": "Spotify",
        "industry": "Music Streaming",
        "location": "Sweden",
        "size": "9000+",
    },
    timeout=30,
)
res.raise_for_status()
audit_id = res.json()["id"]

Watch progress with SSE

Each chunk emits a chunk event as it lands. When all nine chunks complete, you get a done event with the overall score. The stream also pings every 15 s to keep proxies happy.

EventSourcets
// Listen for progress as chunks land
const events = new EventSource(
  `https://audit-api.bjole.dev/audits/${id}/events?api_key=${apiKey}`
);

events.addEventListener("chunk", (e) => {
  const { name, sizeBytes, step } = JSON.parse(e.data);
  console.log(`chunk ${name} ready (${sizeBytes}B) — step ${step}`);
});

events.addEventListener("done", (e) => {
  const { overallScore } = JSON.parse(e.data);
  console.log("audit complete, score:", overallScore);
  events.close();
});

Pull a single chunk

Each section ships as its own JSON blob — pull one at a time, or assemble the whole audit by fetching all nine names. Cross-tenant access returns 404 (same as "not found").

curlbash
curl https://audit-api.bjole.dev/audits/$AUDIT_ID/chunks/risks \
  -H "x-api-key: $AUDIT_API_KEY"

chunk names

metadatacompanyfinancialtechnicalrisksrecommendationsscoreexecutive-summaryindustry-analysisvalidation

the small print

Rate limits, errors, and webhooks.

Rate limits. Soft cap of one concurrent audit per tenant for free-tier accounts; paid tenants get up to ten. Burst above your tier returns 429 with retry-after.

Errors. JSON shape: { error, issues? }. 400 for validation, 401 for missing/bad key, 404 for non-existent or cross-tenant, 429 for rate limit, 5xx for our problems.

Webhooks. Configure a URL in the dashboard and we POST audit.completed / audit.failed events with HMAC-SHA256 signatures (X-Audit-Signature header). Retries with exponential backoff for 24 h.