The live, auto-generated HTTP reference for the Aardvark cloud gateway — rendered inline by the openapi directive on a wide-mode page.
The reference below is the real, user-facing API of the Aardvark cloud
gateway — the metered OpenRouter proxy and dashboard backend behind the
reader assistant. Chat, reader telemetry, dashboard analytics, account and API-key
management, team, billing, and magic-link auth are all here, rendered inline by the
{% openapi %} directive on an ordinary Markdown page set to
mode: wide — no dedicated page generator, just a component.
It also doubles as the headline demonstration of that directive: every operation below is wired into the left-hand nav, with parameter and response tables, multi-language request samples, and a Try it now form. To splice a single endpoint into a page instead of the whole spec, see OpenAPI under Components.
The spec it renders, openapi/aardvark-gateway.json, isn’t hand-written: it’s
extracted from the gateway’s own source — every route’s auth, request fields,
query params, response shape, and error codes — and regenerated on every change, so
this reference can’t drift from the code it documents. (That’s the same drift-proof
loop you’d wire up for your own API.)
Aardvark Gateway API
User-facing HTTP API of the aardvark cloud gateway — the metered OpenRouter proxy and dashboard backend. Operator-only endpoints (/admin/*, /operator-auth/*, /operator-api/*) and the dashboard / operator SPA shells (/dashboard*, /operator*) are excluded by design.
This document is GENERATED from the gateway source: scripts/gen-openapi.mjs extracts every route’s auth, request fields, query params, response shape, and error codes directly from the handlers, then renders them. Do NOT edit openapi.json (or hand-author its structure) — change the code, and regenerate. Only prose lives in scripts/openapi/descriptions.mjs.
https://gateway.aardvarkdocs.comAuthorization
Public widget key, Authorization: Bearer aardvark_live_… . Origin-scoped. Used in the request samples and Try it now below. Held in memory for this session only.
Metered chat completions.
https://gateway.aardvarkdocs.com/v1/chat/completionsOpenAI-compatible chat-completions endpoint. The gateway authorizes the key, reserves the input cost against the account balance, forwards the request to the configured upstream model, and streams the response back as Server-Sent Events while metering actual spend. The system prompt is always injected by the gateway; client-supplied system messages are stripped. The sampling fields (temperature/top_p/frequency_penalty/presence_penalty) are clamped to valid ranges.
Responses
Body
A single string value.
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/chat/completions' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [
{
"role": "user",
"content": "How do I install the CLI?"
}
],
"max_tokens": 512,
"temperature": 0.3
}'Response examples
"string"Reader telemetry ingest.
https://gateway.aardvarkdocs.com/v1/authoring-telemetryScaffold ingest for a future authoring client. Public-key authed like the other reader beacons; event_type is restricted to letters/digits/‘.’/‘_’/‘-’. Best-effort over the per-account daily cap.
Responses
Body
ok | boolean | no | Always true; best-effort ack even when the row is dropped over the daily cap. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/authoring-telemetry' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"event_type": "draft.generated",
"detail": "page=quickstart"
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/commentStores a free-text reader comment, optionally tied to a page path and an island-generated survey/question id. Best-effort over the per-account daily cap. page_url must be a safe site-relative pathname or it is stored as null.
Responses
Body
ok | boolean | no | Always true on accept; best-effort, so true even when the daily cap drops the row. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/comment' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"comment": "The quickstart was great.",
"page_url": "/docs/quickstart"
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/engagementPublic-key beacon (migration 0027): the escalation/contact link was SHOWN under a downvoted answer (escalation_shown) or CLICKED (escalation_click). Decoupled from the transcript and subject to a per-account daily row cap; drives the dashboard’s support-deflection metric.
Responses
Body
ok | boolean | no | Always true on accept; a deduped or over-cap beacon still ACKs 200. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/engagement' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"conversation_id": "c_abc123",
"kind": "escalation_click",
"turn": 0
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/feedbackStores a reader's vote on a specific answer turn. Best-effort: over the per-account daily cap the vote is silently dropped but still returns 200. Deduplicated on (account, conversation_id, turn).
Responses
Body
ok | boolean | no | Always true; the vote is best-effort, so an over-cap drop still ACKs 200. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/feedback' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"vote": "up",
"conversation_id": "c_abc123",
"question": "How do I deploy?",
"turn": 0
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/mcp-telemetryThe docs MCP server posts one beacon per tool call. A short args summary is either supplied (args_summary) or derived from args. Server-side callers (no Origin header) bypass the origin allowlist; browsers must pass it. Best-effort over the per-account daily cap.
Responses
Body
ok | boolean | no | Always true on a 200; the beacon was accepted (also when silently dropped over the daily cap). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/mcp-telemetry' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"tool": "search_docs",
"args_summary": "query=install cli"
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/ratingPublic-key capture of a reader star rating for a page (migration 0036), optionally with a comment. Best-effort over the per-account daily cap.
Responses
Body
ok | boolean | no | Always true on accept; best-effort, so true even when the daily cap drops the row. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/rating' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"rating": 5,
"comment": "Crystal clear.",
"page_url": "/docs/quickstart"
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/search-eventPublic-key batch beacon (migration 0040): the header search box reports settled queries, result clicks, and Ask-AI escalations. Body is { events: [...] }, each event a query, click, or ask_ai. Subject to a per-account daily row cap and dedup; only AI-enabled sites emit. Powers the dashboard’s Search Analytics.
Responses
Body
ok | boolean | no | Always true on accept; a deduped, over-cap, or empty batch still ACKs 200. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/search-event' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"events": [
{
"kind": "query",
"session_id": "s_abc",
"session_seq": 0,
"term": "install",
"results": 3,
"latency_ms": 5
},
{
"kind": "click",
"session_id": "s_abc",
"session_seq": 1,
"term": "install",
"position": 1,
"page_url": "/guide/install/"
}
]
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/surveyPublic-key capture of a structured reader survey answer (migration 0037) — a single/multi choice or a rating — that the Survey island previously sent only to analytics. Best-effort over the per-account daily cap.
Responses
Body
ok | boolean | no | Always true on accept; best-effort, so true even when the daily cap drops the row. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/survey' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"question_type": "rating",
"answer_value": "4",
"rating_value": 4,
"survey_id": "csat",
"question_id": "q1",
"page_url": "/docs/quickstart"
}'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/transcriptUpserts one conversation turn (question + answer, optionally the model’s reasoning) keyed on (key, conversation_id, turn). At least one of question/answer is required. Best-effort over the per-account daily cap; an out-of-range turn is rejected rather than coerced.
Responses
Body
ok | boolean | no | Always true; returned on a stored turn or a best-effort ack over the daily cap. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/transcript' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"conversation_id": "c_abc123",
"turn": 0,
"question": "How do I build my site?",
"answer": "Run `vark build`."
}'Response examples
{
"ok": true
}Dashboard analytics.
https://gateway.aardvarkdocs.com/v1/activityHeadline metrics over the last days (default 30, capped at 365): conversation/answer/feedback counts, verdict mix, uncertainty rate, engagement, support-deflection rate, and top languages.
days | query | integer | no | Window length in days (default 30, capped at 365). |
Responses
Body
window_days | integer | no | Resolved look-back window in days (default 30, capped at 365). |
since | integer | no | Window start, epoch-ms (inclusive); until minus window_days. |
until | integer | no | Window end, epoch-ms (exclusive); the request time. |
conversations | number | no | Distinct conversations with at least one stored turn in the window. |
answers | number | no | Total stored answer turns (transcript rows) in the window. |
feedback | object | no | Reader thumbs vote tallies and the derived satisfaction rate. |
feedback. | string | no | Count of thumbs-up votes on answers in the window. |
feedback. | string | no | Count of thumbs-down votes on answers in the window. |
feedback. | string | no | up / (up + down) in [0,1], or null when no votes. |
verdicts | object | no | Analysis-pass answer-quality classification distribution. |
verdicts. | number | no | Turns classified confident by the analysis pass. |
verdicts. | number | no | Turns classified unconfident by the analysis pass. |
verdicts. | number | no | Turns classified not_found (no answer in the docs). |
verdicts. | number | no | Turns classified doc_gap (a documentation coverage gap). |
analyzed | string | no | Turns with any verdict: sum of the four verdicts counts. |
uncertainty_rate | string | no | Flagged (unconfident+not_found+doc_gap) over analyzed, or null. |
engagement | object | no | Escalation/contact-link beacon counts driving deflection. |
engagement. | number | no | Times the escalation/contact link was shown under a downvoted answer. |
engagement. | number | no | Times a reader clicked the escalation/contact link. |
deflection_rate | string | no | 1 − escalation_click / answers, clamped [0,1]; null when no escalations or answers. |
languages | array<object> | no | Top query languages by turn count (max 12, descending). |
languages[]. | string | no | ISO query-language code from the analysis pass. |
languages[]. | integer | no | Turns analyzed in this language during the window. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/activity?days={days}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"window_days": 0,
"since": 0,
"until": 0,
"conversations": 0,
"answers": 0,
"feedback": {
"up": "string",
"down": "string",
"satisfaction_rate": "string"
},
"verdicts": {
"confident": 0,
"unconfident": 0,
"not_found": 0,
"doc_gap": 0
},
"analyzed": "string",
"uncertainty_rate": "string",
"engagement": {
"escalation_shown": 0,
"escalation_click": 0
},
"deflection_rate": "string",
"languages": [
{
"language": "string",
"count": 0
}
]
}https://gateway.aardvarkdocs.com/v1/authoring-analyticsPer-type counts and the most recent authoring events over the last 90 days. Returns clean empty shapes when no rows exist.
Responses
Body
events | array<object> | no | Per-event_type counts over the last 90 days, busiest type first (≤500 types). |
events[]. | string | no | Client-defined authoring event name, e.g. suggestion_accepted. |
events[]. | integer | no | Number of events of this event_type recorded within the 90-day window. |
recent | array<object> | no | The most recent authoring events, newest first (≤50), within the 90-day window. |
recent[]. | string | no | Client-defined authoring event name for this row. |
recent[]. | string | no | Optional free-text payload sent with the event; null when omitted. |
recent[]. | integer | no | Epoch-ms time the event was recorded. |
total | integer | no | Total events over the last 90 days, summed from the per-type events counts. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/authoring-analytics' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"events": [
{
"event_type": "string",
"count": 0
}
],
"recent": [
{
"event_type": "string",
"detail": "string",
"ts": 0
}
],
"total": 0
}https://gateway.aardvarkdocs.com/v1/conversationsRecent turns grouped into conversations, each with the reader vote and (when available) an automated analysis verdict. filter=needs_attention restricts to low-confidence / doc-gap / not-found turns; verdict/intent/vote/q/tag narrow it further.
verdict | query | string | no | Restrict to a single analysis verdict. |
filter | query | string | no | Set to needs_attention to restrict the result (default all). |
intent | query | string | no | Restrict to a single detected intent. |
vote | query | string | no | Restrict to up/down votes. |
q | query | string | no | Free-text search over question/answer. |
tag | query | string | no | Restrict to a custom tag. |
since | query | integer | no | Epoch-ms lower bound; keeps turns with ts >= this (inclusive). |
until | query | integer | no | Epoch-ms upper bound; keeps turns with ts < this (exclusive). |
Responses
Body
conversations | array<object> | no | Recent turns grouped by conversation_id, newest conversation first, turns ascending within. |
truncated | boolean | no | true when more matching turns exist beyond the 100-turn list cap. |
filter | string | no | Back-compat toggle echo: needs_attention when that legacy filter applied, else all. |
filters | array<string> | no | Active-filter chips, e.g. verdict:doc_gap, intent:troubleshooting, vote:up, tag:<name>, q, date, needs_attention. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/conversations?verdict={verdict}&filter={filter}&intent={intent}&vote={vote}&q={q}&tag={tag}&since={since}&until={until}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"conversations": [
{}
],
"truncated": true,
"filter": "string",
"filters": [
"string"
]
}https://gateway.aardvarkdocs.com/v1/conversations/export.csvCSV of the conversation turns matching the same filters as GET /v1/conversations (every cell formula-injection-guarded). An X-Aardvark-Export-Truncated: true response header signals the export cap was hit.
verdict | query | string | no | Restrict to a single analysis verdict. |
filter | query | string | no | Set to needs_attention to restrict the result (default all). |
intent | query | string | no | Restrict to a single detected intent. |
vote | query | string | no | Restrict to up/down votes. |
q | query | string | no | Free-text search over question/answer. |
tag | query | string | no | Restrict to a custom tag. |
since | query | integer | no | Epoch-ms lower bound; keeps turns with ts >= this (inclusive). |
until | query | integer | no | Epoch-ms upper bound; keeps turns with ts < this (exclusive). |
Responses
Body
A single string value.
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/conversations/export.csv?verdict={verdict}&filter={filter}&intent={intent}&vote={vote}&q={q}&tag={tag}&since={since}&until={until}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
"string"https://gateway.aardvarkdocs.com/v1/digestThe account’s insight-digest opt-in: whether enabled, the cadence, and when it was last_sent_ts.
Responses
Body
enabled | boolean | no | Whether the account is opted into the periodic emailed insights digest; false by default. |
cadence | string | no | Digest frequency, one of week or month; defaults to week. |
last_sent_ts | integer | no | Epoch-ms watermark of the last digest send; 0 when never sent. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/digest' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"enabled": true,
"cadence": "string",
"last_sent_ts": 0
}https://gateway.aardvarkdocs.com/v1/digestOpt the account owner into (or out of) a weekly/monthly emailed insights digest. Owner only. Owner only.
Responses
Body
ok | boolean | no | Always true; the digest preferences were saved. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/digest' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/feedbackThe owner-facing READ of reader thumbs votes — the capture POST is POST /v1/feedback. Returns up/down counts, the satisfaction rate, and recent rated answers. Dashboard-authed (session OR secret key); a public key is rejected at the door.
Responses
Body
up | number | no | Count of thumbs-up votes in the window. |
down | number | no | Count of thumbs-down votes in the window. |
total | integer | no | Total votes (up + down). |
up_rate | string | no | up / (up + down) in [0,1], or null when there are no votes. |
recent | array<object> | no | Recent rated answer turns, newest first. |
recent[]. | integer | no | Epoch-ms time the vote was recorded. |
recent[]. | string | no | Conversation the rated answer belongs to. |
recent[]. | integer | no | Answer index within the conversation. |
recent[]. | string | no | The reader’s verdict, up or down. |
recent[]. | string | no | The rated user question. |
recent[]. | string | no | The rated assistant answer. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/feedback' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"up": 0,
"down": 0,
"total": 0,
"up_rate": "string",
"recent": [
{
"ts": 0,
"conversation_id": "string",
"turn": 0,
"vote": "string",
"question": "string",
"answer": "string"
}
]
}https://gateway.aardvarkdocs.com/v1/feedback/summaryOne cross-stream snapshot of the account's reader feedback over a recent 30-day window — thumbs, page ratings, survey responses, and conversation sentiment — powering the metric tiles at the top of the dashboard Feedback panel. Each sub-stream degrades to zeros if its backing table isn't present yet.
Responses
Body
window_days | integer | no | Look-back window in days for the snapshot (fixed at 30, matching the Insights tab). |
since | integer | no | Epoch-ms start of the window (now - 30 days). |
ratings | string | no | Page star-rating aggregates over the window; zeros until that stream's table lands. |
thumbs | array<any> | no | Thumbs-vote totals over the window (always present — the feedback table ships on main). |
surveys | string | no | Structured survey-response aggregates over the window; zeros until that stream's table lands. |
sentiment | array<any> | no | Conversation-sentiment distribution over the window; zeros until that stream's table lands. |
recent_activity | string | no | A small recent-activity feed across the streams for the panel header. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/feedback/summary' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"window_days": 0,
"since": 0,
"ratings": "string",
"thumbs": [],
"surveys": "string",
"sentiment": [],
"recent_activity": "string"
}https://gateway.aardvarkdocs.com/v1/insight-statusMark a clustered insight (by label) as e.g. triaged/resolved with an optional note — drives the dashboard’s coverage-gap workflow.
Responses
Body
ok | boolean | no | Always true; the gap’s triage status (and note) was recorded. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/insight-status' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/insightsThe cron-clustered analytics surface: live metrics plus Top Questions and Coverage Gaps for the selected period, with prior-period deltas when available.
days | query | integer | no | Rolling window in days. |
period_kind | query | string | no | Named period bucket (e.g. week / month). |
period_start | query | integer | no | Period start, epoch ms. |
Responses
Body
window_days | integer | no | Length of the live-metrics window in days; from ?days=, default 30, capped at 90. |
bucket_ms | integer | no | Volume-series bucket width in ms: 3600000 (hourly) when window <=2 days, else 86400000 (daily). |
since | integer | no | Inclusive start of the live-metrics window, epoch ms (now - window_days*day). |
until | integer | no | Exclusive end of the live-metrics window, epoch ms (request time). |
generated_ts | integer | no | Epoch-ms write time of the shown cluster snapshot (max row ts); null if never clustered. |
period | object | no | The calendar period this Top Questions / Coverage Gaps snapshot covers; null if never clustered. |
period. | string | no | Period granularity: one of week, month, or quarter (legacy for pre-versioning rows). |
period. | string | no | Inclusive start of the period, epoch ms (week = Monday 00:00 UTC). |
period. | string | no | Exclusive end of the period, epoch ms (0 for legacy rows). |
periods | array<object> | no | Navigable history of clustered periods for this kind, newest first. |
periods[]. | string | no | Period granularity of this history entry: week, month, or quarter. |
periods[]. | string | no | Inclusive start of this history period, epoch ms. |
periods[]. | string | no | Exclusive end of this history period, epoch ms. |
has_prior | boolean | no | True when the immediately prior period has clusters to compute per-cluster trends against. |
metrics | object | no | Live engagement metrics over the ?days= window (computed on demand, not snapshotted). |
metrics. | number | no | Count of answer turns (transcripts) in the window. |
metrics. | number | no | Count of distinct conversations in the window. |
metrics. | object | no | Reader thumbs-up/down tallies over the window. |
metrics. | number | no | Number of thumbs-up votes in the window. |
metrics. | number | no | Number of thumbs-down votes in the window. |
metrics. | object | no | Distribution of analysis classifications over turns in the window. |
metrics. | number | no | Turns classified confident by the analysis pass. |
metrics. | number | no | Turns classified unconfident by the analysis pass. |
metrics. | number | no | Turns classified not_found (no answer found) by the analysis pass. |
metrics. | number | no | Turns classified doc_gap (a documentation gap) by the analysis pass. |
metrics. | array<object> | no | Turns-per-time-bucket volume series (sparse; client fills gaps), oldest first. |
metrics. | integer | no | Bucket start, epoch ms, floored to bucket_ms. |
metrics. | integer | no | Number of turns falling in this bucket. |
metrics. | object | no | Escalation/contact-link beacon counts driving the support-deflection metric. |
metrics. | number | no | Times the escalation/contact link was shown under a downvoted answer. |
metrics. | number | no | Times the escalation/contact link was clicked. |
metrics. | array<object> | no | Reader query-language distribution, most-frequent first (top 12). |
metrics. | string | no | Detected query language (from conversation_analysis.language). |
metrics. | integer | no | Number of turns in this language within the window. |
top_questions | array<object> | no | Clustered Top Questions for the period, biggest cluster first. |
top_questions[]. | string | no | Short human label naming the question theme. |
top_questions[]. | integer | no | Approximate number of reader questions in this cluster. |
top_questions[]. | string | no | Up to 3 representative example questions for this cluster. |
coverage_gaps | array<object> | no | Clustered Coverage Gaps (flagged turns grouped into doc-gap topics), biggest first. |
coverage_gaps[]. | string | no | Short human label naming the coverage-gap topic. |
coverage_gaps[]. | string | no | What readers asked and why the assistant struggled (may be null). |
coverage_gaps[]. | string | no | Concrete documentation change that would fix the gap (may be null). |
coverage_gaps[]. | integer | no | Approximate number of flagged turns in this cluster. |
coverage_gaps[]. | string | no | Up to 3 representative example questions for this gap. |
coverage_gaps[]. | string | no | Triage state set via /v1/insight-status; defaults to open when untouched. |
coverage_gaps[]. | string | no | Optional triage note attached to this gap; null when none. |
coverage_gaps[]. | string | no | Epoch-ms time the gap's triage status was last set; null when untouched. |
sources | object | no | Doc-page citation analytics over the metrics window. |
sources. | array<object> | no | Most-cited doc pages in the window, busiest first (up to 20). |
sources. | string | no | Site-relative path of the cited documentation page. |
sources. | number | no | Times this page was cited as a source in the window. |
sources. | number | no | Of those citations, how many sat on a downvoted answer. |
sources. | integer | no | Total source-citation events recorded across all pages in the window. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/insights?days={days}&period_kind={period_kind}&period_start={period_start}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"window_days": 0,
"bucket_ms": 0,
"since": 0,
"until": 0,
"generated_ts": 0,
"period": {
"kind": "string",
"start": "string",
"end": "string"
},
"periods": [
{
"kind": "string",
"start": "string",
"end": "string"
}
],
"has_prior": true,
"metrics": {
"turns": 0,
"conversations": 0,
"votes": {
"up": 0,
"down": 0
},
"verdicts": {
"confident": 0,
"unconfident": 0,
"not_found": 0,
"doc_gap": 0
},
"series": [
{
"bucket_ts": 0,
"count": 0
}
],
"engagement": {
"escalation_shown": 0,
"escalation_click": 0
},
"languages": [
{
"language": "string",
"count": 0
}
]
},
"top_questions": [
{
"label": "string",
"count": 0,
"examples": "string"
}
],
"coverage_gaps": [
{
"label": "string",
"finding": "string",
"recommendation": "string",
"count": 0,
"examples": "string",
"status": "string",
"note": "string",
"status_updated_at": "string"
}
],
"sources": {
"pages": [
{
"page": "string",
"citations": 0,
"downvoted": 0
}
],
"total": 0
}
}https://gateway.aardvarkdocs.com/v1/insights/assistantNatural-language Q&A over the account's analytics. Metered against the account balance (it calls the model), so it can return 402/429/502/503 like the chat endpoint.
Responses
Body
answer | string | no | Natural-language reply about the account's analytics; a canned message when no data exists yet. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/insights/assistant' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"answer": "string"
}https://gateway.aardvarkdocs.com/v1/mcp-analyticsTop tools, recent calls, and a bucketed time series over a window of days (default 7, max 90). Buckets are hourly for ≤2 days, daily otherwise.
days | query | integer | no | Window in days (1–90). |
Responses
Body
window_days | integer | no | Resolved look-back window in days (?days=, default 7, capped at 90). |
bucket_ms | integer | no | Time-series bucket width in ms: hourly (3600000) for windows ≤2 days, else daily (86400000). |
since | integer | no | Epoch-ms start of the window (inclusive); until minus window_days. |
until | integer | no | Epoch-ms end of the window (exclusive); the request time now. |
tools | array<object> | no | Per-tool call counts in the window, ordered by count descending then tool name. |
tools[]. | string | no | MCP tool name as beaconed by the docs MCP server. |
tools[]. | integer | no | Number of calls to this tool within the window. |
recent | array<object> | no | Most recent individual tool calls, newest first, up to 100. |
recent[]. | string | no | MCP tool name for this individual call. |
recent[]. | string | no | Short human-readable summary of the call’s arguments; null when none was recorded. |
recent[]. | integer | no | Epoch-ms time the tool call was recorded. |
series | array<object> | no | Sparse per-bucket call counts over the window; only non-empty buckets, ascending by time. |
series[]. | integer | no | Epoch-ms floored start of the bucket (ts floored to bucket_ms). |
series[]. | integer | no | Number of tool calls falling in this bucket. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/mcp-analytics?days={days}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"window_days": 0,
"bucket_ms": 0,
"since": 0,
"until": 0,
"tools": [
{
"tool": "string",
"count": 0
}
],
"recent": [
{
"tool": "string",
"args_summary": "string",
"ts": 0
}
],
"series": [
{
"bucket_ts": 0,
"count": 0
}
]
}https://gateway.aardvarkdocs.com/v1/page-ratingsThe dashboard READ of reader star ratings: the overall average, total count, and a per-page breakdown. Dashboard-authed like /v1/insights.
Responses
Body
overall_avg | number | no | Mean star rating across all pages, or null when there are no ratings. |
total | integer | no | Total number of ratings submitted. |
pages | array<any> | no | Per-page rating rollups (path, average, count), busiest first. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/page-ratings' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"overall_avg": 0,
"total": 0,
"pages": []
}https://gateway.aardvarkdocs.com/v1/search-analyticsOn-site search analytics over a window of days (default 30, max 90): top searches, zero-result queries, click-through, average clicked position, searches-per-session, no-click rate, Ask-AI escalation rate, top clicked pages, a language split, and a bucketed volume series (hourly for ≤2 days, daily otherwise).
days | query | integer | no | Window in days (1–90; default 30). |
Responses
Body
window_days | integer | no | Resolved look-back window in days (?days=, default 30, capped at 90). |
bucket_ms | integer | no | Time-series bucket width in ms: hourly (3600000) for windows ≤2 days, else daily (86400000). |
since | integer | no | Epoch-ms start of the window (inclusive). |
until | integer | no | Epoch-ms end of the window (exclusive); the request time now. |
totals | object | no | |
totals. | number | no | Number of search queries in the window. |
totals. | number | no | Number of result clicks in the window. |
totals. | number | no | Number of Ask-AI escalations from search. |
totals. | number | no | Distinct search sessions in the window. |
totals. | number | no | Number of queries that returned no results. |
ctr | number | no | Clicks divided by queries (a ratio; can exceed 1 when a reader opens several results for one search). |
askAiRate | number | no | Ask-AI escalations divided by queries. |
searchesPerSession | number | no | Queries divided by distinct sessions. |
noClickSessionRate | number | no | Fraction of searching sessions that never clicked a result. |
avgPosition | number | no | Mean 1-based rank of clicked results; omitted when there are no clicks. |
avgLatencyMs | number | no | Mean client-side scorer time in ms; omitted when no latency was reported. |
topTerms | array<object> | no | |
topTerms[]. | string | no | A representative raw query term for the group. Searches are grouped by an accent-folded/lowercased key (so "café"/"Cafe"/"CAFÉ" count as one), but the displayed term is a real raw variant, not the folded key. |
topTerms[]. | number | no | Number of searches for this term (across all accent/case variants of it). |
topTerms[]. | number | no | How many of those searches returned no results. |
zeroResultTerms | array<object> | no | |
zeroResultTerms[]. | string | no | A representative raw query term that returned nothing (a content gap), grouped by the same accent-folded/lowercased key as topTerms. |
zeroResultTerms[]. | number | no | Number of zero-result searches for this term. |
topClickedPages | array<object> | no | |
topClickedPages[]. | string | no | A clicked result page path. |
topClickedPages[]. | number | no | Number of clicks to this page from search. |
byLang | array<object> | no | |
byLang[]. | string | no | Reader/page language tag. |
byLang[]. | number | no | Number of queries in this language. |
series | array<object> | no | |
series[]. | number | no | Epoch-ms floored start of the bucket. |
series[]. | number | no | Number of queries in this bucket. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/search-analytics?days={days}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"window_days": 0,
"bucket_ms": 0,
"since": 0,
"until": 0,
"totals": {
"queries": 0,
"clicks": 0,
"askAi": 0,
"sessions": 0,
"zeroResults": 0
},
"ctr": 0,
"askAiRate": 0,
"searchesPerSession": 0,
"noClickSessionRate": 0,
"avgPosition": 0,
"avgLatencyMs": 0,
"topTerms": [
{
"term": "string",
"searches": 0,
"zeroResults": 0
}
],
"zeroResultTerms": [
{
"term": "string",
"count": 0
}
],
"topClickedPages": [
{
"page": "string",
"clicks": 0
}
],
"byLang": [
{
"lang": "string",
"count": 0
}
],
"series": [
{
"bucket_ts": 0,
"count": 0
}
]
}https://gateway.aardvarkdocs.com/v1/sentimentThe positive/neutral/negative distribution of analyzed conversations over a recent window, plus recent example messages, for the reader-feedback panel. Dashboard-authed like /v1/insights.
Responses
Body
positive | integer | no | Count of conversations the analysis pass classified positive. |
neutral | integer | no | Count classified neutral. |
negative | integer | no | Count classified negative. |
total | integer | no | Total classified conversations (positive + neutral + negative). |
recent_positive | string | no | A few recent example messages classified positive. |
recent_negative | string | no | A few recent example messages classified negative. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/sentiment' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"positive": 0,
"neutral": 0,
"negative": 0,
"total": 0,
"recent_positive": "string",
"recent_negative": "string"
}https://gateway.aardvarkdocs.com/v1/surveysThe dashboard READ of structured survey answers: per-question aggregates (choice bars + rating averages) plus recent open-ended survey comments. Dashboard-authed like /v1/usage.
Responses
Body
surveys | array<object> | no | Per-survey question aggregates. |
surveys[]. | string | no | Island-defined question id. |
surveys[]. | string | no | Question kind: single, multi, rating, or text. |
surveys[]. | integer | no | Number of respondents to the question. |
surveys[]. | integer | no | Number of rating answers folded into rating_avg. |
surveys[]. | array<object> | no | Per-option counts for a choice question, most-picked first. |
surveys[]. | string | no | The chosen option label. |
surveys[]. | integer | no | How many respondents picked this option. |
surveys[]. | string | no | Mean of the rating answers, or null for a non-rating question / no ratings. |
comments | array<object> | no | Recent open-ended survey comments (the survey-scoped page_comments rows). |
comments[]. | integer | no | Epoch-ms time the comment was submitted. |
comments[]. | string | no | Site-relative path the comment was left on, or null. |
comments[]. | string | no | Reader-supplied open-ended comment text (escaped before display). |
truncated | boolean | no | true when more comments exist beyond the returned cap. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/surveys' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"surveys": [
{
"question_id": "string",
"question_type": "string",
"total": 0,
"rating_count": 0,
"choices": [
{
"value": "string",
"count": 0
}
],
"rating_avg": "string"
}
],
"comments": [
{
"ts": 0,
"page_url": "string",
"comment": "string"
}
],
"truncated": true
}https://gateway.aardvarkdocs.com/v1/tagsThe account’s custom tag vocabulary (tags) and the per-account cap (max).
Responses
Body
tags | array<object> | no | The account’s active (non-deleted) custom tags, sorted alphabetically by name. |
tags[]. | string | no | Opaque UUID identifying the tag. |
tags[]. | string | no | Display label of the tag, unique per account; no semicolons or control characters. |
tags[]. | string | no | Optional guidance steering how the analysis pass applies this tag; null if unset. |
tags[]. | integer | no | Epoch-ms time the tag was created. |
tags[]. | number | no | Count of conversations currently labeled with this tag. |
max | number | no | Maximum active tags allowed per account (default 20). |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/tags' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"tags": [
{
"id": "string",
"name": "string",
"description": "string",
"ts": 0,
"uses": 0
}
],
"max": 0
}https://gateway.aardvarkdocs.com/v1/tagsAdd a custom tag to the account vocabulary. Owner/admin only; 409 on a duplicate name or when the per-account cap is reached. Owner only.
Responses
Body
ok | boolean | no | Always true once the tag is created and added to the account vocabulary. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/tags' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/tags/{id}Edit a tag’s description and/or soft-delete it (deleted: true hides it from the vocabulary without dropping the labels already applied to conversations). Owner/admin only; at least one of description/deleted must be supplied, and 404 if no tag matches the id. Owner only.
id | path | string | yes | Tag id — the trailing path segment after /v1/tags/ (≤100 chars). |
Responses
Body
ok | boolean | no | Always true once the update (or soft-delete) is applied. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/tags/{id}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/v1/threadsA flat, cursor-paged feed of answer turns in ascending (ts, conversation_id, turn) order (oldest first) — built for forward incremental sync. Page with next_cursor / has_more.
since | query | integer | no | Cursor: return turns at or after this epoch-ms timestamp (inclusive lower bound), or pass a prior page’s next_cursor. |
limit | query | integer | no | Max turns to return. |
Responses
Body
turns | array<object> | no | Page of recent answer turns, ascending by the (ts, conversation_id, turn) sort key. |
turns[]. | string | no | Conversation this turn belongs to; the reader-island session/thread id. |
turns[]. | integer | no | Zero-based turn index within the conversation. |
turns[]. | string | no | The reader's question text for this turn; null if not stored. |
turns[]. | string | no | The assistant's answer text for this turn; null if not stored. |
turns[]. | string | no | Full model reasoning for the turn (not truncated); null if absent. |
turns[]. | integer | no | Epoch-ms time the transcript turn was recorded; the pagination sort key. |
turns[]. | string | no | Reader feedback: up, down, or null when no vote was cast. |
turns[]. | string | no | Analysis verdict: confident, unconfident, not_found, or doc_gap; null until analyzed. |
turns[]. | string | no | One-sentence analysis summary of the turn; null until analyzed. |
turns[]. | string | no | Conversation kind: troubleshooting, product_discovery, unsupported_feature, competitor, or off_topic; else null. |
turns[]. | string | no | Reader question’s language as a short ISO code (e.g. en, ja, pt-BR); null if unknown. |
count | integer | no | Number of turns returned on this page. |
next_cursor | string | no | Opaque continuation token to pass as since; null when no further page remains. |
has_more | boolean | no | True when another non-empty page exists beyond this one. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/threads?since={since}&limit={limit}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"turns": [
{
"conversation_id": "string",
"turn": 0,
"question": "string",
"answer": "string",
"reasoning": "string",
"ts": 0,
"vote": "string",
"classification": "string",
"summary": "string",
"intent": "string",
"language": "string"
}
],
"count": 0,
"next_cursor": "string",
"has_more": true
}https://gateway.aardvarkdocs.com/v1/transcriptsReturns the account’s stored transcripts grouped into conversations (newest first), each turn carrying its vote. Capped at ~300 turns; truncated signals older history exists.
Responses
Body
conversations | array<object> | no | Stored conversations, newest first; each holds its turns (turn, question, answer, vote) ascending. |
truncated | boolean | no | true when older turns exist beyond the ~300-turn cap and were omitted. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/transcripts' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"conversations": [
{}
],
"truncated": true
}https://gateway.aardvarkdocs.com/v1/usageThe dashboard overview payload: account status, balance, recent usage rows, top-ups, reader feedback/comments, account events, and the payment/auto-top-up configuration. Readable even when the account is suspended.
Responses
Body
account | object | no | Account identity and current standing block. |
account. | string | no | The caller's account id. |
account. | string | no | Billing-account owner’s email from the accounts row (not a member’s address). |
account. | string | no | Account state, e.g. active, suspended, closed, or unknown if the row is missing. |
account. | object | no | Active-suspension summary when status is suspended; otherwise null. |
account. | string | no | Why the account was paused: cost_unavailable, operator, or self_serve. |
account. | integer | no | Epoch-ms time the suspension was recorded. |
account. | string | no | Request id that triggered the suspension, for support correlation. |
account. | boolean | no | Whether the dashboard Reactivate button applies; true only for a cost_unavailable pause. |
balance | object | no | Current balance snapshot from the Durable Object, in USD. |
balance. | number | no | Total account balance in USD. |
balance. | number | no | Funds reserved against in-flight requests, in USD. |
balance. | number | no | Spendable balance in USD (balance_usd minus reserved_usd). |
anomaly_paused | boolean | no | Whether the spend-velocity circuit breaker has paused paid AI (free models keep serving). Visible to every caller; resuming is owner/admin via POST /v1/billing/resume-ai. |
subscription | object | no | The account’s live subscription plan + included-AI grant meter (the same object GET /v1/billing returns), or null on the free pay-as-you-go plan. Present only for owner/admin callers; omitted for members. |
usage | array<object> | no | Up to 50 most recent metered-request ledger rows, newest first. |
usage[]. | integer | no | Epoch-ms time the usage row was written. |
usage[]. | string | no | Upstream model slug billed for the request. |
usage[]. | integer | no | Input token count for the request. |
usage[]. | integer | no | Output token count for the request. |
usage[]. | number | no | Published OpenRouter list cost in USD (pre-markup; not the operator's backend cost). |
usage[]. | number | no | Amount charged to the account in USD (list cost times markup). |
usage[]. | string | no | Upstream generation id used to reconcile the final cost. |
usage[]. | string | no | How the cost was derived: inline, generation_api, or provisional. |
usage[]. | string | no | |
topups | array<object> | no | Up to 20 most recent balance credits, newest first. Present only for owner/admin callers; omitted for members. |
topups[]. | integer | no | Epoch-ms time the top-up was credited. |
topups[]. | number | no | Credited amount in USD. |
topups[]. | string | no | Origin of the credit, e.g. stripe, auto_topup, or an operator grant. |
topups[]. | string | no | Optional free-text note attached to the credit. |
feedback | array<object> | no | Up to 50 most recent reader thumbs votes, newest first. |
feedback[]. | integer | no | Epoch-ms time the vote was recorded. |
feedback[]. | string | no | Conversation the rated answer belongs to. |
feedback[]. | string | no | Reader’s verdict, up or down. |
feedback[]. | string | no | The reader question that the rated answer addressed. |
comments | array<object> | no | Up to 50 most recent reader page comments, newest first. |
comments[]. | integer | no | Epoch-ms time the comment was submitted. |
comments[]. | string | no | Site-relative path the comment was left on, or null. |
comments[]. | string | no | Reader-supplied open-ended comment text (escaped before display). |
events | array<object> | no | Up to 20 most recent account decision-log entries, newest first. |
events[]. | integer | no | Epoch-ms time the event was recorded. |
events[]. | string | no | Decision type: suspended, reactivated, or closed. |
events[]. | string | no | Reason code: cost_unavailable, operator, or self_serve. |
events[]. | string | no | Who made the change: system, operator, owner, or admin. |
events[]. | string | no | Request id correlated with the event, if any. |
payment | object | no | Card-on-file and auto-top-up configuration for the Billing section. Present only for owner/admin callers; omitted for members. |
payment. | boolean | no | Whether the gateway has a Stripe secret key and can accept card payments at all. |
payment. | boolean | no | Whether a card is saved on file for the account. |
payment. | object | no | Display-only details of the saved card, or null when none. |
payment. | string | no | Card brand, e.g. visa. |
payment. | string | no | Last four digits of the saved card. |
payment. | integer | no | Card expiry month, 1-12. |
payment. | integer | no | Card expiry year, four digits. |
payment. | boolean | no | Whether auto top-up is turned on. |
payment. | number | no | Amount charged per auto top-up in USD, or null when unset. |
payment. | integer | no | Consecutive auto-top-up charge failures since the last success. |
payment. | string | no | Message from the most recent auto-top-up failure, or null. |
payment. | integer | no | Available-balance threshold in USD that triggers an auto top-up. |
payment. | number | no | Minimum allowed auto-top-up charge amount in USD. |
payment. | number | no | Maximum allowed top-up amount in USD (Stripe per-charge technical limit). |
payment_events | array<object> | no | Up to 20 most recent billing-activity entries (card lifecycle, declined charges), newest first. Present only for owner/admin callers; omitted for members. |
payment_events[]. | integer | no | Epoch-ms time the payment event was recorded. |
payment_events[]. | string | no | Event type, e.g. card saved/removed or a charge succeeded/declined. |
payment_events[]. | number | no | Charge amount in USD, or null for non-charge events. |
payment_events[]. | string | no | Free-text detail about the event, e.g. a decline reason. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/usage' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"account": {
"id": "string",
"owner_email": "string",
"status": "string",
"suspension": {
"reason": "string",
"ts": 0,
"request_id": "string",
"self_serviceable": true
}
},
"balance": {
"balance_usd": 0,
"reserved_usd": 0,
"available_usd": 0
},
"anomaly_paused": true,
"subscription": {},
"usage": [
{
"ts": 0,
"model": "string",
"prompt_tokens": 0,
"completion_tokens": 0,
"openrouter_usd": 0,
"billed_usd": 0,
"generation_id": "string",
"cost_source": "string",
"source": "string"
}
],
"topups": [
{
"ts": 0,
"amount_usd": 0,
"source": "string",
"note": "string"
}
],
"feedback": [
{
"ts": 0,
"conversation_id": "string",
"vote": "string",
"question": "string"
}
],
"comments": [
{
"ts": 0,
"page_url": "string",
"comment": "string"
}
],
"events": [
{
"ts": 0,
"event": "string",
"reason": "string",
"actor": "string",
"request_id": "string"
}
],
"payment": {
"stripe_enabled": true,
"has_card": true,
"card": {
"brand": "string",
"last4": "string",
"exp_month": 0,
"exp_year": 0
},
"auto_topup_enabled": true,
"auto_topup_amount_usd": 0,
"auto_topup_failures": 0,
"auto_topup_last_error": "string",
"low_balance_usd": 0,
"min_usd": 0,
"max_usd": 0
},
"payment_events": [
{
"ts": 0,
"type": "string",
"amount_usd": 0,
"detail": "string"
}
]
}https://gateway.aardvarkdocs.com/v1/usage/membersOwner/admin billing usage grouped by the team member who minted each key, over an optional [since, until) window. Account-owned secret/admin/CLI usage is listed as one row per key with safe key metadata.
since | query | integer | no | Inclusive lower bound, epoch ms (default: 30 days ago). |
until | query | integer | no | Exclusive upper bound, epoch ms (default: now). |
Responses
Body
since | integer | no | Inclusive start of the resolved [since, until) window, epoch-ms. |
until | integer | no | Exclusive end of the resolved [since, until) window, epoch-ms (clamped to now). |
members | array<object> | no | Usage groups, sorted by spend descending with member rows before account-owned key rows on ties. |
members[]. | string | no | User who minted the keys, or null for an account-owned key row. |
members[]. | string | no | Member’s email, or null for an account-owned key row or a since-deleted user. |
members[]. | string | no | Id of the account-owned key this row aggregates, or null for a member-attributed row. |
members[]. | string | no | Non-secret prefix of the account-owned key, or null for a member-attributed row. |
members[]. | string | no | Display label of the account-owned key, or null for a member-attributed row. |
members[]. | string | no | public or secret for an account-owned key row, or null for a member-attributed row. |
members[]. | boolean | no | true when this row aggregates an account-owned key (user_id is null) rather than a member. |
members[]. | boolean | no | Back-compat alias for is_account_key; true when user_id is null. |
members[]. | string | no | Display name: key label/prefix for account-owned key rows, else the member email, else (member <id8>) for a deleted user. |
members[]. | integer | no | Number of usage-ledger rows (requests) attributed to this member or account-owned key. |
members[]. | integer | no | Summed prompt (input) tokens across this row's requests. |
members[]. | integer | no | Summed completion (output) tokens across this row's requests. |
members[]. | integer | no | Sum of prompt_tokens and completion_tokens for this row. |
members[]. | number | no | Total amount billed to this row over the window, in USD. |
totals | object | no | Grand-total summary across all rows for the window. |
totals. | integer | no | Total requests across all rows over the window. |
totals. | integer | no | Total prompt (input) tokens across all rows. |
totals. | integer | no | Total completion (output) tokens across all rows. |
totals. | integer | no | Sum of prompt_tokens and completion_tokens across all rows. |
totals. | number | no | Total amount billed across all rows over the window, in USD (summed in micro-USD, converted once). |
support | object | no | |
support. | array<object> | no | |
support. | string | no | |
support. | string | no | |
support. | string | no | |
support. | integer | no | |
support. | integer | no | |
support. | integer | no | |
support. | integer | no | |
support. | number | no | |
support. | object | no | |
support. | integer | no | |
support. | integer | no | |
support. | integer | no | |
support. | integer | no | |
support. | number | no |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/usage/members?since={since}&until={until}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"since": 0,
"until": 0,
"members": [
{
"user_id": "string",
"email": "string",
"key_id": "string",
"key_prefix": "string",
"key_label": "string",
"key_mode": "string",
"is_account_key": true,
"is_cli": true,
"label": "string",
"requests": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"billed_usd": 0
}
],
"totals": {
"requests": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"billed_usd": 0
},
"support": {
"users": [
{
"user_id": "string",
"email": "string",
"label": "string",
"requests": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"billed_usd": 0
}
],
"totals": {
"requests": 0,
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0,
"billed_usd": 0
}
}
}Support tickets.
https://gateway.aardvarkdocs.com/v1/supportLists tickets for the account. Plain members see only their own; owners/admins/secret-key callers see the whole account. Capped at 100 (newest first).
Responses
Body
items | array<object> | no | Support tickets for the account, newest first, capped at 100. |
items[]. | string | no | Ticket's UUID, assigned at submission. |
items[]. | string | no | Ticket kind: one of bug, feature, question, or other. |
items[]. | string | no | Submitter's free-text message, capped at 4000 characters. |
items[]. | string | no | Triage state; defaults to open at creation. |
items[]. | integer | no | Epoch-ms time the ticket was submitted. |
truncated | boolean | no | true when more than 100 tickets exist beyond those returned. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/support' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"items": [
{
"id": "string",
"category": "string",
"message": "string",
"status": "string",
"ts": 0
}
],
"truncated": true
}https://gateway.aardvarkdocs.com/v1/supportFiles a ticket to the gateway operator. Fail-hard over the per-account daily cap (429). Sends a best-effort operator email; the stored row is the source of truth.
Responses
Body
ok | boolean | no | Always true once the ticket row is stored. |
id | string | no | Server-minted UUID of the stored support ticket. |
status | string | no | Initial triage status of a new ticket; always open. |
ts | integer | no | Epoch-ms time the ticket was stored. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/support' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"category": "bug",
"message": "The usage chart is blank on Safari."
}'Response examples
{
"ok": true,
"id": "string",
"status": "string",
"ts": 0
}In-dashboard support assistant.
https://gateway.aardvarkdocs.com/v1/assistant/chatOne metered turn of the dashboard support assistant. The gateway injects the system prompt (identity, plan-and-approve behavior, the docs index) and the account context, forces the latest Sonnet model, and forwards the conversation to the upstream model. Billed to the account (tagged as support spend), so it can return 402/429/503 like the chat endpoint. The reply may include tool_calls the dashboard renders for the user to approve before running.
Responses
Body
role | string | no | Always assistant. |
content | string | no | The assistant's reply text (may be null on a pure tool-call turn). |
tool_calls | array<object> | no | Proposed tool calls from the known menu, for the user to approve; empty on a final answer. |
billed_usd | number | no | What this turn cost the account, in USD (published rate). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/assistant/chat' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"role": "string",
"content": "string",
"tool_calls": [
{}
],
"billed_usd": 0
}https://gateway.aardvarkdocs.com/v1/assistant/docServer-side fetch of one aardvark documentation page (Markdown) for the assistant’s fetch_doc grounding tool. The path is validated to a same-origin .md page and the body is size-capped.
path | query | string | no | The docs page’s .md path (relative, no scheme/traversal), e.g. ai-gateway.md. |
Responses
Body
path | string | no | The resolved page path. |
text | string | no | The page's Markdown, truncated to the size cap. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/assistant/doc?path={path}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"path": "string",
"text": "string"
}https://gateway.aardvarkdocs.com/v1/assistant/escalateFile a support ticket (a GitHub issue in the operator’s repo) with the chat history, attempted actions, and account details, for a human to handle. Per-account rate-limited. Records the escalation and mirrors it to the support list; if GitHub filing is unavailable it still records + mirrors and reports filed: false.
Responses
Body
ok | boolean | no | Always true once the escalation is recorded. |
filed | boolean | no | Whether a GitHub issue was actually created. |
issue_number | integer | no | The created issue number, or null if not filed. |
issue_url | string | no | The created issue URL, or null if not filed. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/assistant/escalate' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"ok": true,
"filed": true,
"issue_number": 0,
"issue_url": "string"
}Account self-service.
https://gateway.aardvarkdocs.com/v1/reactivateLifts the gateway's automatic cost-unavailable suspension. Operator-set holds and closed accounts cannot be reactivated here. Idempotent. Owner/admin only.
Responses
Body
status | string | no | Account status after the call; active on every success path. |
changed | boolean | no | true if this call lifted the pause; false when already active (no-op). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/reactivate' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"status": "string",
"changed": true
}API key management.
https://gateway.aardvarkdocs.com/v1/keysReturns metadata for every key on the account (prefix, mode, label, allowed origins, revoked flag) — never the hash or secret value.
Responses
Body
keys | array<object> | no | Every API key on the account, ordered by mode then created_at; metadata only. |
keys[]. | string | no | Opaque key identifier, used as :id in the per-key management routes. |
keys[]. | string | no | Key class: public (origin-gateable reader key) or secret (account master credential). |
keys[]. | string | no | Short non-secret prefix of the key value, shown to identify the key. |
keys[]. | string | no | Human-set display nickname, or null if unnamed. |
keys[]. | array<string> | no | Origin allowlist for a public key (null means any origin); always null for secret keys. |
keys[]. | boolean | no | Whether the key has been revoked and can no longer authenticate. |
keys[]. | number | no | Epoch-ms time the key was minted. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/keys' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"keys": [
{
"id": "string",
"mode": "string",
"key_prefix": "string",
"label": "string",
"allowed_origins": [
"string"
],
"revoked": true,
"created_at": 0
}
]
}https://gateway.aardvarkdocs.com/v1/keysCreates a public or secret key. The full key value is returned ONCE. Secret keys are owner-only and capped at one active per account (rotate to replace). Public keys may be origin-scoped.
Responses
Body
key_id | string | no | UUID row id of the newly minted key, for later rotate/revoke/update calls. |
api_key | string | no | The full key value — shown ONCE. |
key_prefix | string | no | First 20 chars of the key (aardvark_live_ or aardvark_secret_ plus a slice), shown for identification. |
mode | string | no | Key class: public (origin-gated, site-embedded) or secret (full account/CLI credential). |
label | string | no | Display nickname stored for the key; defaults to aardvark <mode> when none given. |
warnings | array<string> | no | Advisory notices, e.g. an unscoped public key accepting any origin or a risky wildcard origin. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/keys' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"mode": "public",
"label": "docs site",
"allowed_origins": [
"https://docs.example.com"
]
}'Response examples
{
"key_id": "string",
"api_key": "string",
"key_prefix": "string",
"mode": "string",
"label": "string",
"warnings": [
"string"
]
}https://gateway.aardvarkdocs.com/v1/keys/{id}Updates a key's label and/or a public key's allowed origins. At least one field is required; an omitted field is left unchanged. Non-owners may only update keys they created.
id | path | string | yes | Identifier of the key to update. |
Responses
Body
allowed_origins | array<any> | no | Origin allowlist now set on the public key; null means any origin is accepted. |
warnings | array<string> | no | Non-fatal advisories, e.g. unrestricted-origin or shared-wildcard cautions about the new config. |
label | string | no | New display nickname after the rename; null when the label was cleared or omitted. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/keys/{id}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"allowed_origins": [],
"warnings": [
"string"
],
"label": "string"
}https://gateway.aardvarkdocs.com/v1/keys/{id}/revokePermanently revokes a PUBLIC key. Secret keys cannot be bare-revoked (rotate them instead) to avoid locking the owner out.
id | path | string | yes | Identifier of the public key to revoke. |
Responses
Body
revoked | boolean | no | Always true on success; a missing or non-public key returns a 404 error instead. |
key_id | string | no | Id of the public key that was revoked, echoing the path {id}. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/keys/{id}/revoke' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"revoked": true,
"key_id": "string"
}https://gateway.aardvarkdocs.com/v1/keys/{id}/rotateRevokes the key and mints a same-mode replacement atomically. The new value is shown once. Non-owners may only rotate keys they created; a demoted member cannot rotate the account secret key.
id | path | string | yes | Identifier of the key to rotate. |
Responses
Body
key_id | string | no | Id of the freshly minted replacement key (a new UUID). |
api_key | string | no | The full replacement key value — shown ONCE. |
key_prefix | string | no | Display prefix of the new key value (mode-dependent: public vs secret prefix). |
mode | string | no | Mode carried over to the replacement: public or secret. |
rotated_from | string | no | Id of the now-revoked original key this replacement supersedes. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/keys/{id}/rotate' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"key_id": "string",
"api_key": "string",
"key_prefix": "string",
"mode": "string",
"rotated_from": "string"
}Team & invites.
https://gateway.aardvarkdocs.com/v1/teamReturns the account's members. Owners/admins also see pending invites; plain members see members only.
Responses
Body
members | array<object> | no | Active members on the shared billing account, oldest membership (the owner) first. |
members[]. | string | no | Stable id of the member's user record. |
members[]. | string | no | Member’s login email, joined from the users table. |
members[]. | string | no | Member’s tier on the account: owner, admin, or member. |
members[]. | string | no | Membership state; always active here (invited/removed rows are excluded). |
members[]. | number | no | Epoch-ms time the membership was created (account join). |
invites | array<object> | no | Pending unconsumed invites; present only for owner/admin callers, else empty. |
invites[]. | string | no | Email the invite was sent to (not yet accepted). |
invites[]. | string | no | Role the invite will grant on accept: member or admin. |
invites[]. | number | no | Epoch-ms time the invite link expires (~7 days after issue). |
invites[]. | number | no | Epoch-ms time the invite was issued; newest invites listed first. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/team' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"members": [
{
"user_id": "string",
"email": "string",
"role": "string",
"status": "string",
"created_at": 0
}
],
"invites": [
{
"email": "string",
"role": "string",
"expires_at": 0,
"created_at": 0
}
]
}https://gateway.aardvarkdocs.com/v1/team/inviteOwner/admin only. Emails a magic invite link (valid ~7 days). Owners may invite admins; admins may invite members only. Invites never grant owner. Returns 409 without sending when the plan's editor seats are already in use; acceptance rechecks the snapshotted allowance atomically. Otherwise the response is a neutral 200 regardless of delivery.
Responses
Body
ok | boolean | no | Always true; the neutral success acknowledgment (returned regardless of email delivery). |
email | string | no | Normalized email address the invite link was sent to. |
role | string | no | Role the invitee will hold on accepting; member or admin (never owner). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/team/invite' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"email": "teammate@example.com",
"role": "member"
}'Response examples
{
"ok": true,
"email": "string",
"role": "string"
}https://gateway.aardvarkdocs.com/v1/team/invite/revokeOwner/admin only. Cancels an unconsumed invite for an email. Idempotent (revoked: 0 when none pending).
Responses
Body
ok | boolean | no | Always true once the request validates; the cancel ran (even if nothing matched). |
email | string | no | Normalized invitee email whose pending invite was targeted, echoed back. |
revoked | number | no | Count of pending (unconsumed) invite tokens deleted; 0 when none were pending. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/team/invite/revoke' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"email": "teammate@example.com"
}'Response examples
{
"ok": true,
"email": "string",
"revoked": 0
}https://gateway.aardvarkdocs.com/v1/team/removeOwner/admin only, with a last-owner guard. Admins may remove non-owners. Removal revokes the member's keys and deletes their invites first.
Responses
Body
ok | boolean | no | true once the member is removed and their keys/invites revoked. |
user_id | string | no | Echoes back the removed member's user id. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/team/remove' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"user_id": "u_abc123"
}'Response examples
{
"ok": true,
"user_id": "string"
}https://gateway.aardvarkdocs.com/v1/team/roleOwner/admin only, with a last-owner guard. Non-owners cannot grant or alter owner/admin. Demotions revoke the member's keys before the change.
Responses
Body
ok | boolean | no | Always true when the role change was applied successfully. |
user_id | string | no | Identifier of the member whose role was changed. |
role | string | no | The member’s new role: owner, admin, or member. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/team/role' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"user_id": "u_abc123",
"role": "admin"
}'Response examples
{
"ok": true,
"user_id": "string",
"role": "string"
}Card & top-ups.
https://gateway.aardvarkdocs.com/v1/billingThe subscription-plan catalog (Free/Pro/Business/Enterprise — operator-editable data), the account's live subscription with its included-AI grant meter (dollars used, the account's own trailing burn rate, an estimated depletion date), the anomaly-breaker state, and recent subscription events. Owner/admin only, like the other billing surfaces.
Responses
Body
plans | array<object> | no | The plan catalog, cheapest first. |
plans[]. | string | no | Stable plan slug: free, pro, business, enterprise (operator may add more). |
plans[]. | string | no | Display name. |
plans[]. | number | no | Monthly platform price in USD (0 for Free and custom-only plans). |
plans[]. | number | no | Annual price for 12 months in USD (20% off the platform fee, with the grant funded monthly at par — an effective ~12% off the yearly total, up to ~13% on plans whose bundled allowance is a smaller share of the fee), or null when annual isn't offered. |
plans[]. | number | no | Included AI per month, in dollars of BILLED usage (the same units the ledger bills — never opaque credits). |
plans[]. | integer | no | The plan's published member markup over OpenRouter list cost, ×100 (150 = ×1.50 Free baseline, 140 = ×1.40 Pro, 130 = ×1.30 Business, 120 = ×1.20 Enterprise). |
plans[]. | integer | no | Editor seats included with the plan. |
plans[]. | number | no | Per-seat monthly price of an add-on editor seat on this plan, in USD (0 = the plan sells no add-on seats). Annual subscriptions bill seats at this rate ×12 at par. Exposed so a plan-change confirmation can disclose the seat-charge delta a switch imposes on an account already holding add-on seats. |
plans[]. | boolean | no | Whether the plan is open in the catalog (a retired plan keeps existing subscribers but takes no new ones). |
plans[]. | boolean | no | Whether the plan can be subscribed to directly (the Free/PAYG row is the 'no subscription' state and is never self-serve). |
subscription | object | no | The live subscription + grant meter: plan/status/interval (+ cancel_at when a cancellation is scheduled), grant (monthly/remaining/rollover/available USD + period bounds), overflow (mode/cap/used + the 2× acknowledgment), seats (add-on editor seats: included/addon/used/limit counts + seat_price_usd per-seat monthly price), burn (last-30-days USD, per-day rate, estimated depletion date), and max_bill_usd — the single worst-case-bill number. Null on the free pay-as-you-go plan. |
anomaly_paused | boolean | no | Whether the spend-velocity circuit breaker has paused paid AI (free models keep serving). |
events | array<object> | no | Up to 20 most recent subscription lifecycle events, newest first. |
events[]. | string | no | Event kind: subscribed, plan_changed, canceled, cancel_unscheduled, grant_reset, overflow_changed, payment_failed, payment_recovered, downgraded, paused, resumed, seats_changed. |
events[]. | string | no | Who performed it: owner, admin (a team admin acting for the account), operator, or system. |
events[]. | string | no | Event-specific JSON detail, or null. |
events[]. | integer | no | Epoch-ms time of the event. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/billing' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"plans": [
{
"id": "string",
"name": "string",
"price_usd": 0,
"price_annual_usd": 0,
"monthly_grant_usd": 0,
"markup_x100": 0,
"seats_included": 0,
"seat_price_usd": 0,
"active": true,
"self_serve": true
}
],
"subscription": {},
"anomaly_paused": true,
"events": [
{
"event": "string",
"actor": "string",
"detail": "string",
"ts": 0
}
]
}https://gateway.aardvarkdocs.com/v1/billing/cancelA Stripe-billed subscription cancels at PERIOD END (the customer keeps what they paid for; the webhook performs the downgrade at the boundary) — the scheduled end date is surfaced as the subscription’s cancel_at until then. Pass resume: true to UNDO a scheduled cancellation (409 no_pending_cancel when none is scheduled). An operator-granted subscription downgrades immediately. The prepaid balance is never touched by a lapse.
Responses
Body
resumed | boolean | no | true when a scheduled cancellation was undone (resume: true). |
subscription | object | no | The refreshed subscription payload (carries the updated cancel_at). |
canceled | boolean | no | true when a cancellation was scheduled (or performed immediately). |
at_period_end | boolean | no | true when the plan stays active until the paid period ends; false when the downgrade was immediate (operator-granted). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/billing/cancel' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"resumed": true,
"subscription": {},
"canceled": true,
"at_period_end": true
}Switch the live subscription to another plan (upgrades apply immediately; downgrades at the next boundary)
https://gateway.aardvarkdocs.com/v1/billing/change-planSwitches the live subscription to another plan. An UPGRADE (a higher-priced plan) applies IMMEDIATELY — the Stripe price is swapped with the difference prorated onto the next invoice, and the grant/markup/seats re-snapshot now. A DOWNGRADE (a lower-priced plan) is SCHEDULED for the next billing boundary with NO current-period proration: the current plan’s entitlement and billing continue unchanged until then, and the switch applies at that period’s invoice.paid (the response reports the scheduled plan via pending_plan, and switching back before the boundary unschedules it). At most ONE off-cycle re-grant applies per grant period regardless of how many times plans are swapped (swap-proof grant minting). Operator-managed (non-Stripe) subscriptions are refused — the operator re-plans via the admin surface.
Responses
Body
changed | boolean | no | Always true on success. |
effective | string | no | |
subscription | object | no | The updated subscription + grant meter (same shape as GET /v1/billing’s subscription). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/billing/change-plan' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"changed": true,
"effective": "string",
"subscription": {}
}https://gateway.aardvarkdocs.com/v1/billing/overflowWhat happens when the monthly included AI runs out: cap_hold (default — paid AI pauses; the plan price is the worst-case bill), payg_fallback (overflow draws the prepaid balance at the plan’s member markup, up to the cap), or shutoff. Raising the cap past 2× the monthly grant requires the explicit acknowledgment.
Responses
Body
ok | boolean | no | Always true on success. |
mode | string | no | The saved overflow mode. |
cap_usd | number | no | The saved overflow cap in USD. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/billing/overflow' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"ok": true,
"mode": "string",
"cap_usd": 0
}https://gateway.aardvarkdocs.com/v1/billing/resume-aiLifts the spend-velocity circuit breaker's pause and prevents the same tripped UTC-day spend bucket from immediately re-triggering it; spend attributed to any other UTC day is evaluated normally. Works on every plan including Free — the breaker guards the pay-as-you-go tier too.
Responses
Body
resumed | boolean | no | Always true. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/billing/resume-ai' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"resumed": true
}https://gateway.aardvarkdocs.com/v1/billing/seatsSets the ABSOLUTE number of purchased add-on editor seats on a Stripe-billed subscription (migration 0045). The plan’s seats_included are free; each add-on seat bills at the plan’s per-seat monthly rate. Seats are block-and-buy — invites are refused with 403 seat_limit at the limit until more are bought here, so the bill never grows without this call. A REDUCTION can’t drop below the seats already occupied (members + pending invites). Operator-managed (non-Stripe) subscriptions are refused. A positive purchase on a plan that sells no add-on seats is refused with 400 seats_not_available, but a REMOVAL (seats: 0) is NOT blocked by that guard even after a plan’s per-seat price has been zeroed — so a customer holding a still-billing seat item can shed it rather than be trapped. (A removal is still subject to the same 400 seats_in_use floor as any reduction — it can’t drop the limit below the seats already occupied by members + pending invites — and to the suspended/closed-account guards.)
Responses
Body
seats_included | integer | no | The plan's included seats (free). |
seats_addon | integer | no | The purchased add-on seat count now in effect. |
seat_price_usd | number | no | The current per-add-on-seat monthly price. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/billing/seats' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"seats_included": 0,
"seats_addon": 0,
"seat_price_usd": 0
}https://gateway.aardvarkdocs.com/v1/billing/subscribeCreates the Stripe subscription for a self-serve plan and grants the first month’s included AI immediately. Requires a card on file (see POST /v1/payment/checkout). Overflow defaults to cap-and-hold at 1× the grant, so the plan price is also the worst-case bill until the customer opts into fallback.
Responses
Body
subscribed | boolean | no | Always true on success. |
subscription | object | no | The new subscription + grant meter (same shape as GET /v1/billing’s subscription). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/billing/subscribe' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"subscribed": true,
"subscription": {}
}https://gateway.aardvarkdocs.com/v1/payment/autotopupSets the auto-top-up on/off state, charge amount, and low-balance trigger. At least one field is required; the trigger must be below the charge amount. Enabling requires a saved card and an amount. Owner/admin only.
Responses
Body
auto_topup_enabled | boolean | no | Post-write on/off state of auto top-up after this update. |
auto_topup_amount_usd | number | no | Amount charged per auto top-up, in USD; null when none is stored. |
low_balance_usd | number | no | Low-balance trigger threshold in USD that arms an auto top-up. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/payment/autotopup' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"enabled": true,
"amount_usd": 50,
"low_balance_usd": 20
}'Response examples
{
"auto_topup_enabled": true,
"auto_topup_amount_usd": 0,
"low_balance_usd": 0
}https://gateway.aardvarkdocs.com/v1/payment/checkoutCreates (if needed) a Stripe customer and a hosted SetupIntent Checkout Session, returning the redirect URL. No body required. Owner/admin only.
Responses
Body
url | string | no | Redirect URL of the hosted Stripe SetupIntent Checkout Session for card entry. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/payment/checkout' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"url": "string"
}https://gateway.aardvarkdocs.com/v1/payment/methodServer-side re-reads the completed Checkout Session, verifies it belongs to this account, and stores the card on file. Idempotent on a given session_id. Owner/admin only.
Responses
Body
card | object | no | Non-sensitive details of the card now saved on file, for display. |
card. | string | no | Card network brand (e.g. visa, mastercard); null if Stripe omitted it. |
card. | string | no | Last four digits of the saved card; null if unavailable. |
card. | integer | no | Card expiry month, 1–12; null if unavailable. |
card. | integer | no | Card expiry year, four-digit; null if unavailable. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/payment/method' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"session_id": "cs_test_abc123"
}'Response examples
{
"card": {
"brand": "string",
"last4": "string",
"exp_month": 0,
"exp_year": 0
}
}https://gateway.aardvarkdocs.com/v1/payment/methodClears the card on file (also disabling auto-top-up) and best-effort detaches it at Stripe. Idempotent; allowed even when card payments are disabled. Owner/admin only.
Responses
Body
removed | boolean | no | Always true; confirms the card on file was cleared and auto-top-up disabled. |
Request samples
curl -X DELETE 'https://gateway.aardvarkdocs.com/v1/payment/method' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"removed": true
}https://gateway.aardvarkdocs.com/v1/payment/topup-nowImmediately charges the saved card for amount_usd and credits the balance. Use a client idempotency_key to make retries safe. A pending charge returns { pending: true } and is credited by the webhook. Set reactivate: true to lift a self-serviceable (cost-unavailable) suspension before charging, so one call reactivates and tops up. Owner/admin only.
Responses
Body
pending | boolean | no | Present when the charge is still settling. |
balance_usd | number | no | New balance after the credit (on a synchronous charge). |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/payment/topup-now' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"amount_usd": 50,
"idempotency_key": "topup-2026-06-25-1"
}'Response examples
{
"pending": true,
"balance_usd": 0
}Magic-link sign-in.
https://gateway.aardvarkdocs.com/auth/logoutDeletes the session row and clears the cookie. Requires the session cookie and the X-Aardvark-Dashboard CSRF header. Idempotent.
Try it now unavailable
This auth endpoint is same-origin to the gateway dashboard, so browser calls from this docs page are blocked by CORS. Use a generated request sample or the dashboard instead.
Responses
Body
ok | boolean | no | Always true; the session row was deleted and the __Host-av_session cookie cleared. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/auth/logout' \
-H 'Cookie: __Host-av_session=YOUR_API_KEY'Response examples
{
"ok": true
}https://gateway.aardvarkdocs.com/auth/meReturns the authenticated user, the active account, the role there, and all memberships. Returns 401 { authenticated: false } when there is no valid session.
Try it now unavailable
This auth endpoint is same-origin to the gateway dashboard, so browser calls from this docs page are blocked by CORS. Use a generated request sample or the dashboard instead.
Responses
Body
authenticated | boolean | no | true for a valid session; the 401 body instead carries false. |
user | object | no | The signed-in user identity (id and login email). |
user. | string | no | Stable user id of the signed-in account holder. |
user. | string | no | Login email of the signed-in user. |
active_account | string | no | Account id the session is currently scoped to for billing and /v1/* access. |
role | string | no | Caller’s role in active_account: one of owner, admin, or member. |
memberships | array<object> | no | All accounts the user is an active member of, for the account switcher. |
memberships[]. | string | no | Account id of this membership. |
memberships[]. | string | no | User’s role on that account: owner, admin, or member. |
memberships[]. | string | no | Owner email of that account, shown to identify it in the switcher. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/auth/me' \
-H 'Cookie: __Host-av_session=YOUR_API_KEY'Response examples
{
"authenticated": true,
"user": {
"id": "string",
"email": "string"
},
"active_account": "string",
"role": "string",
"memberships": [
{
"account_id": "string",
"role": "string",
"owner_email": "string"
}
]
}https://gateway.aardvarkdocs.com/auth/request-linkEmails a single-use magic link to the address. Neutral 200 regardless of whether the email exists (no account enumeration). Rate limited per IP and per email.
Try it now unavailable
This auth endpoint is same-origin to the gateway dashboard, so browser calls from this docs page are blocked by CORS. Use a generated request sample or the dashboard instead.
Responses
Body
ok | boolean | no | Always true; the response is neutral and never signals whether the email exists. |
message | string | no | Neutral confirmation prose shown regardless of outcome, avoiding account enumeration. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/auth/request-link' \
-H 'Content-Type: application/json' \
-d '{
"email": "user@example.com"
}'Response examples
{
"ok": true,
"message": "string"
}https://gateway.aardvarkdocs.com/auth/switchRotates the session to a different account the user belongs to. Requires the session cookie and the X-Aardvark-Dashboard CSRF header. Rate limited per user.
Try it now unavailable
This auth endpoint is same-origin to the gateway dashboard, so browser calls from this docs page are blocked by CORS. Use a generated request sample or the dashboard instead.
Responses
Body
ok | boolean | no | Always true once the session is rotated to the target account. |
active_account | string | no | Account id the session is now active on, matching the requested account_id. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/auth/switch' \
-H 'Cookie: __Host-av_session=YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"account_id": "a_abc123"
}'Response examples
{
"ok": true,
"active_account": "string"
}https://gateway.aardvarkdocs.com/auth/verifyServes a tiny nonce-CSP HTML page that reads the token from the URL fragment and POSTs it to /auth/verify. The token never reaches the server as a query string.
Try it now unavailable
This endpoint serves the magic-link verification HTML page, not a cross-origin JSON API request. Open the magic link in your browser or start the flow from the dashboard instead.
Responses
Body
A single string value.
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/auth/verify'Response examples
"string"https://gateway.aardvarkdocs.com/auth/verifyThe token in the body is the credential. On success sets the __Host-av_session cookie. NOTE: this endpoint’s responses use the non-standard shape { ok, error } (read by the landing page’s script), not the usual error envelope.
Try it now unavailable
This auth endpoint is same-origin to the gateway dashboard, so browser calls from this docs page are blocked by CORS. Use a generated request sample or the dashboard instead.
Responses
Body
ok | boolean | no | true when the token was consumed and the __Host-av_session cookie was minted; false carries an error code. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/auth/verify' \
-H 'Content-Type: application/json' \
-d '{
"token": "<base64url-token>"
}'Response examples
{
"ok": true
}Stripe webhooks.
https://gateway.aardvarkdocs.com/v1/stripe/webhookStripe-to-server webhook authenticated by the Stripe-Signature header (HMAC over the raw body). Handles payment_intent.succeeded (durable credit) and payment_intent.payment_failed (audit + auto-top-up streak), plus the subscription lifecycle (migration 0044): customer.subscription.created/customer.subscription.updated (snapshot sync, plan reconcile, lost-insert heal), customer.subscription.deleted (downgrade to Free), invoice.paid (billing history, past-due recovery, scheduled-downgrade apply at the boundary), and invoice.payment_failed (dunning + past_due grace clock). Acks 200 once a delivery is handled or irrelevant; deliberately returns 500 on transient read/write failures so Stripe redelivers instead of losing a money event.
Try it now unavailable
This endpoint is server-to-server only, so browser calls from this docs page are blocked by CORS. Use a generated request sample from your backend instead.
Responses
Body
received | boolean | no | Always true; acks the verified delivery so Stripe stops its retry storm. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/stripe/webhook' \
-H 'Stripe-Signature: YOUR_API_KEY'Response examples
{
"received": true
}Docs quality checks.
https://gateway.aardvarkdocs.com/v1/github/capabilitiesThe static catalog of AI authoring capabilities (e.g. keyword and description generation, the style-guide pass) that can be enabled to run on a connected repo. Readable by any authenticated dashboard user.
Responses
Body
capabilities | string | no | The catalog of available authoring capabilities, each with its id, label, and runner command. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/github/capabilities' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"capabilities": "string"
}https://gateway.aardvarkdocs.com/v1/github/configureDeclarative per-repo automation config: for each capability set whether it’s enabled, its schedule (cron, floored to at most once per hour), run-on-push, base branch, and project dir. A pure DB apply — no GitHub writes. Owner only. Owner only.
Responses
Body
repo | string | no | Echoes the configured repo owner/name. |
automations | array<object> | no | The repo's automation rows after the apply. |
automations[]. | string | no | Capability id this automation runs. |
automations[]. | string | no | Whether the automation is active after the apply. |
automations[]. | string | no | Whether a matching push fires the automation. |
automations[]. | string | no | Resolved 5-field cron schedule, or null when unscheduled. |
automations[]. | string | no | Branch the automation runs against, or null for the repo default. |
automations[]. | string | no | Subdirectory the vark project lives in, or null for the repo root. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/configure' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"repo": "acme/docs",
"automations": [
{
"capability": "keywords",
"enabled": true,
"run_on_push": true,
"cron": "0 9 * * 1",
"base_branch": "main"
}
]
}'Response examples
{
"repo": "string",
"automations": [
{
"capability": "string",
"enabled": "string",
"run_on_push": "string",
"cron": "string",
"base_branch": "string",
"project_dir": "string"
}
]
}https://gateway.aardvarkdocs.com/v1/github/connectMints a single-use install state and returns the GitHub App install URL carrying it. The browser follows that URL; GitHub echoes state back to the setup callback, which binds the installation to this account. Owner only. Owner only.
Responses
Body
install_url | string | no | GitHub App install URL with the single-use state embedded; redirect the browser here to start the install. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/connect' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"install_url": "string"
}https://gateway.aardvarkdocs.com/v1/github/connectionEverything the dashboard's Docs Quality Checks page needs: whether the integration is configured, the install-URL slug, the account's installations, and each connected repo with its per-capability automation config.
Responses
Body
configured | boolean | no | Whether the gateway is fully configured for the integration (app creds, slug, webhook secret, OAuth creds). |
app_slug | string | no | The GitHub App's URL slug used to build the install URL, or null when unset. |
capabilities | string | no | The static catalog of AI authoring capabilities that can be enabled per repo. |
installations | array<object> | no | GitHub App installations bound to this account. |
installations[]. | string | no | GitHub's numeric installation id. |
installations[]. | string | no | The org/user login the app is installed on. |
installations[]. | string | no | Installation account type, e.g. Organization or User. |
installations[]. | boolean | no | true when GitHub has suspended the installation. |
installations[]. | boolean | no | true when GitHub no longer recognizes this installation id (the app was reinstalled) — reconnect to fix. |
repos | array<object> | no | Repos reachable through the installations, each with its automation config. |
repos[]. | string | no | Repo owner/name. |
repos[]. | string | no | Repo default branch (the automation base when none is set). |
repos[]. | string | no | Whether the repo is private. |
repos[]. | string | no | Installation that grants access to this repo. |
repos[]. | integer | no | true when the repo has at least one automation set up. |
repos[]. | array<object> | no | Per-capability automation rows configured on the repo. |
repos[]. | string | no | Capability id this automation runs. |
repos[]. | string | no | Whether the automation is active. |
repos[]. | string | no | Whether a matching push fires the automation. |
repos[]. | string | no | Schedule (5-field cron, at most hourly), or null. |
repos[]. | string | no | Branch the automation runs against, or null for the repo default. |
repos[]. | string | no | Subdirectory the vark project lives in, or null for the repo root. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/github/connection' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"configured": true,
"app_slug": "string",
"capabilities": "string",
"installations": [
{
"installation_id": "string",
"github_login": "string",
"account_type": "string",
"suspended": true,
"stale": true
}
],
"repos": [
{
"full_name": "string",
"default_branch": "string",
"private": "string",
"installation_id": "string",
"configured": 0,
"automations": [
{
"capability": "string",
"enabled": "string",
"run_on_push": "string",
"cron": "string",
"base_branch": "string",
"project_dir": "string"
}
]
}
]
}https://gateway.aardvarkdocs.com/v1/github/disconnectStops all automations for a repo by dropping their config rows in one atomic delete. Leaves the app installed (uninstall happens in GitHub) and the repo listed so it can be reconfigured. Owner only. Owner only.
Responses
Body
disconnected | boolean | no | Always true once the repo’s automations are removed. |
repo | string | no | Echoes the repo that was disconnected. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/disconnect' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"repo": "acme/docs"
}'Response examples
{
"disconnected": true,
"repo": "string"
}https://gateway.aardvarkdocs.com/v1/github/runDispatches a configured capability immediately on the central runner. The run is recorded as queued and advanced by the runner’s claim/complete callbacks. A balance or runner-config problem returns 402/503; an already-running capability returns 409. Owner only. Owner only.
Responses
Body
dispatched | boolean | no | Always true when the run was queued on the central runner. |
run_id | string | no | Server-minted UUID of the queued run, for correlating later run-history rows. |
repo | string | no | Echoes the repo the run was dispatched for. |
capability | string | no | Echoes the capability the run executes. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/run' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"repo": "acme/docs",
"capability": "keywords"
}'Response examples
{
"dispatched": true,
"run_id": "string",
"repo": "string",
"capability": "string"
}https://gateway.aardvarkdocs.com/v1/github/run/cancelCancels the active queued or in-progress run for a repo/capability pair, revokes any already-minted ephemeral inference key, and best-effort cancels the backing GitHub Actions run. Idempotent: idle pairs return cancelled: false. Owner only.
Responses
Body
cancelled | boolean | yes | true when an active run was sealed as cancelled; false when no matching run was active. |
run_id | string | no | Server-minted UUID of the cancelled run. Present only when cancelled is true. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/run/cancel' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"repo": "acme/docs",
"capability": "keywords"
}'Response examples
{
"cancelled": true,
"run_id": "string"
}https://gateway.aardvarkdocs.com/v1/github/runner/claimCentral-runner callback: the runner claims a queued run and receives an ephemeral inference key plus a repo-scoped GitHub token (minted only once the claim CAS wins). Authed by the runner credential (RUNNER_CALLBACK_TOKEN and/or a GitHub Actions OIDC JWT), never a dashboard session.
Try it now unavailable
This endpoint is server-to-server only, so browser calls from this docs page are blocked by CORS. Use a generated request sample from your backend instead.
Responses
Body
inference_key | string | no | Ephemeral, per-run secret inference key — returned ONCE, after the claim CAS wins. |
repo_token | string | no | Short-lived GitHub token scoped to the customer repo (contents + pull-requests write). |
command | string | no | The vark runner command to execute for this capability. |
full_name | string | no | Customer repo owner/name the run targets. |
installation_id | string | no | Installation id whose token grants access to the customer repo. |
base_branch | string | no | Branch to run against, or null for the repo default. |
project_dir | string | no | Subdirectory the vark project lives in, or null for the repo root. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/runner/claim' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"run_id": "1f0c…",
"github_run_id": 1234567890
}'Response examples
{
"inference_key": "string",
"repo_token": "string",
"command": "string",
"full_name": "string",
"installation_id": "string",
"base_branch": "string",
"project_dir": "string"
}https://gateway.aardvarkdocs.com/v1/github/runner/completeCentral-runner callback: reports a finished run. Revokes the run's ephemeral key (stops spend), meters the compute, and records the conclusion plus the PR it opened. Idempotent; a late callback can top up a $0-sealed run. Authed by the runner credential.
Try it now unavailable
This endpoint is server-to-server only, so browser calls from this docs page are blocked by CORS. Use a generated request sample from your backend instead.
Responses
Body
ok | boolean | no | Always true once the run is finalized (or already was). |
already_finalized | boolean | no | Present and true when the run was already billed — an idempotent no-op. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/runner/complete' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"run_id": "1f0c…",
"billable_ms": 42000,
"conclusion": "success",
"pr_url": "https://github.com/acme/docs/pull/7",
"github_run_id": 1234567890
}'Response examples
{
"ok": true,
"already_finalized": true
}https://gateway.aardvarkdocs.com/v1/github/runsRun history for a connected repo, newest first, optionally filtered by capability. Each row carries status, conclusion, the PR the run opened, and the metered compute cost.
repo | query | string | yes | Repo owner/name to list runs for (required). |
capability | query | string | no | Restrict to one capability's runs. |
limit | query | integer | no | Max rows to return (default 50, capped at 200). |
Responses
Body
repo | string | no | Echoes the queried repo owner/name. |
runs | array<object> | no | Run-history rows, newest first. |
runs[]. | string | no | Stable run UUID (the React table key; run_number is null until the run starts). |
runs[]. | string | no | Capability the run executed. |
runs[]. | string | no | What started the run: manual, push, or schedule. |
runs[]. | string | no | Lifecycle state: queued, in_progress, completed, or skipped. |
runs[]. | string | no | GitHub Actions conclusion (e.g. success, failure), or null until finished. |
runs[]. | string | no | Why a skipped run never started (e.g. insufficient_balance), or null. |
runs[]. | string | no | GitHub Actions run number on our runner repo, or null until claimed. |
runs[]. | string | no | URL of the PR the run opened in the customer repo, or null. |
runs[]. | integer | no | Metered compute cost in micro-USD, or null until finalized. |
runs[]. | string | no | Epoch-ms time the run was created. |
runs[]. | string | no | Epoch-ms time the run row was last updated. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/github/runs?repo={repo}&capability={capability}&limit={limit}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"repo": "string",
"runs": [
{
"id": "string",
"capability": "string",
"trigger": "string",
"status": "string",
"conclusion": "string",
"skip_reason": "string",
"run_number": "string",
"pr_url": "string",
"compute_billed_micro": 0,
"created_at": "string",
"updated_at": "string"
}
]
}https://gateway.aardvarkdocs.com/v1/github/runs/{run_id}Deletes one terminal GitHub automation run from the account’s dashboard history. Queued and in-progress runs must be cancelled first because they still gate dispatch and key cleanup. Owner only.
run_id | path | string | yes | Stable run UUID from GET /v1/github/runs. |
Responses
Body
deleted | boolean | yes | Always true once the history entry is removed. |
run_id | string | yes | Echoes the cleared run UUID. |
Request samples
curl -X DELETE 'https://gateway.aardvarkdocs.com/v1/github/runs/{run_id}' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"deleted": true,
"run_id": "string"
}https://gateway.aardvarkdocs.com/v1/github/runs/{run_id}/logsReturns the latest GitHub Actions job log text for one Docs Quality Check run. The dashboard polls this endpoint while a row is expanded so queued and in-progress runs can surface logs as soon as GitHub publishes them.
run_id | path | string | yes | Stable run UUID from GET /v1/github/runs. |
Responses
Body
run_id | string | yes | Echoes the requested run UUID. |
status | string | yes | Current dashboard run status. |
available | boolean | yes | false until the runner has claimed the run and GitHub has a job log to download. |
logs | string | yes | Normalized text log payload, or an empty string while unavailable. |
truncated | boolean | yes | true when only the tail of an oversized log is returned. |
job | object | no | GitHub Actions job metadata for the selected runner job, or null while unavailable. |
job. | number | no | |
job. | string | no | |
job. | string | no | |
job. | string | no | |
updated_at | integer | yes | Epoch-ms time this log response was generated (refreshed on every request), not a run-row change stamp. |
message | string | no | Human-readable unavailable-state message. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/github/runs/{run_id}/logs' \
-H 'Authorization: Bearer YOUR_API_KEY'Response examples
{
"run_id": "string",
"status": "string",
"available": true,
"logs": "string",
"truncated": true,
"job": {
"id": 0,
"name": "string",
"status": "string",
"conclusion": "string"
},
"updated_at": 0,
"message": "string"
}https://gateway.aardvarkdocs.com/v1/github/setupGitHub redirects the browser here after the app is installed or updated. The single-use state (minted at connect) recovers which account initiated, an identity check proves the user administers the installation, then it binds the install, syncs repos, and 302-redirects back to the dashboard. Authed by state, not a session.
state | query | string | no | Single-use install state minted at connect; the credential that recovers and binds the initiating account. |
installation_id | query | integer | no | GitHub's numeric id for the new/updated installation. |
code | query | string | no | OAuth code GitHub appends so the gateway can prove the user administers this installation. |
Try it now unavailable
This endpoint is a browser redirect callback, not a cross-origin API call. Start the GitHub connection flow from the dashboard instead.
Responses
Headers
Location | string | Dashboard URL to follow, carrying ?connected=1 on success or ?error=<code> otherwise. |
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/v1/github/setup?state={state}&installation_id={installation_id}&code={code}&state=YOUR_API_KEY'Response examples
{
"error": {
"code": "github_misconfigured",
"message": "The gateway origin is misconfigured; contact the operator."
}
}https://gateway.aardvarkdocs.com/v1/github/webhookGitHub-to-server webhook authenticated by the X-Hub-Signature-256 HMAC over the raw body. Handles installation lifecycle, repo-selection changes, pushes (run-on-push automations), workflow runs (a backstop for the runner’s complete callback), and PRs (PR-url capture). Acks 200 once verified; unrecognized event types are acked and ignored.
Try it now unavailable
This endpoint is server-to-server only, so browser calls from this docs page are blocked by CORS. Use a generated request sample from your backend instead.
Responses
Body
received | boolean | no | Always true; acks the verified delivery so GitHub stops retrying. |
Request samples
curl -X POST 'https://gateway.aardvarkdocs.com/v1/github/webhook' \
-H 'X-Hub-Signature-256: YOUR_API_KEY'Response examples
{
"received": true
}Health check.
https://gateway.aardvarkdocs.com/Unauthenticated root health check; returns a fixed text/plain body.
Responses
Body
A single string value.
Request samples
curl -X GET 'https://gateway.aardvarkdocs.com/'Response examples
"string"