REST API
Base URL: https://vaka.example.com/api/v1. The OpenAPI document is at https://vaka.example.com/api/v1/openapi.json.
The MCP server uses the same query layer, so both return the same data.
Authentication
Authorization: Bearer vt_...
API tokens are created by admins in the admin UI (Tokens) or with POST /api/v1/tokens.
Each token is either scoped to one project or to all projects, and is either read or write.
Signed-in admin UI sessions also work (cookie), which is handy for quick browser checks.
Errors are {"error": "explanation"} with a 4xx/5xx status. 401 means a missing or bad token,
403 a token without access to that project or without write scope.
Conventions
{p}is a project slug or id.{id}for issues is the id or short id (WEB-12).- Time parameters (
since,until,window,baseline) take a relative duration (30m,24h,7d), an RFC 3339 timestamp, or unix milliseconds. - Timestamps in responses are RFC 3339 UTC.
- Stack traces are crash site first:
frames[0]is where the error was raised.
Projects and keys
| Method & path | Description |
|---|---|
GET /me |
The current user or token and its access |
GET /projects |
Projects you can access |
POST /projects |
Create: {"name", "platform", "slug"?}. Platforms: javascript, android, ios, rust, node, jvm, go, dotnet, python, other. Returns ingest_key and install_instructions_url |
GET /projects/{p} |
One project |
PATCH /projects/{p} |
Admin: {"name"?, "retention_days"?, "scrub_enabled"?, "scrub_fields"?} (scrub_fields: comma-separated extra keys) |
POST /projects/{p}/keys |
Create another ingest key |
DELETE /projects/{p}/keys/{key} |
Revoke an ingest key |
GET /projects/{p}/install/{platform} |
Install guide as Markdown with key and endpoint filled in (javascript, android, ios, rust, http) |
Issues and events
| Method & path | Description |
|---|---|
GET /projects/{p}/issues |
status (open|resolved|ignored|all, default open), query (title/culprit text), release, environment, since (count window, default 24h), sort (last_seen|first_seen|times_seen|events|users), limit |
GET /issues/{id} |
Issue with latest event (symbolicated frames, source context, breadcrumbs, tags) and breakdowns by release, OS, device, browser |
PATCH /issues/{id} |
{"status"?: "open"|"resolved"|"ignored", "resolved_in_release"?, "ignore_for"?: "7d", "assignee"?: "email" or ""} |
GET /issues/{id}/events |
Recent events (limit) |
POST /issues/{id}/comments |
{"body": "markdown"} |
GET /projects/{p}/events |
Search error events: query, level, release, environment, user_id, exception_type, since, until, limit |
GET /projects/{p}/events/{event_id} |
One event in full |
A resolved issue that receives a new event is reopened and marked as a regression (and fires
regression alerts). With resolved_in_release, only events from that release or newer count.
Releases
| Method & path | Description |
|---|---|
GET /projects/{p}/releases |
Known releases |
GET /projects/{p}/releases/health |
Crash-free sessions and users, sessions, errors and new issues per release; release, since |
GET /projects/{p}/releases/compare?base=1.2.0&target=1.3.0 |
Health side by side, new issues, gone issues, issues that increased |
GET /projects/{p}/explain-spike |
Why errors went up: window (default 1h) vs baseline (default the 24h before), ranked by issue, release, OS, device, country, exception type |
Analytics
| Method & path | Description |
|---|---|
GET /projects/{p}/analytics/summary |
Visitors, pageviews, screen views, custom events, identified users, with the previous period |
GET /projects/{p}/analytics/timeseries |
Same metrics per interval (hour|day|week|month) |
GET /projects/{p}/analytics/breakdown |
Top values of dimension, ranked by visitors; limit |
Common parameters: since, until, type (pageview|screen_view|custom), and repeated
filter=dimension:value (prefix the value with ~ for contains or ! for not equal).
Dimensions: path, url, hostname, referrer (referrer host or UTM source), referrer_url,
utm_source, utm_medium, utm_campaign, utm_term, utm_content, country, device,
device_model, browser, browser_version, os, os_version, app_version, release,
environment, platform, event (event name), type, screen, and prop:<name> for custom
event properties.
curl -H "Authorization: Bearer $VAKA_TOKEN" \
"https://vaka.example.com/api/v1/projects/web/analytics/breakdown?dimension=prop:plan&filter=event:signup&since=30d"
Debug files
| Method & path | Description |
|---|---|
GET /projects/{p}/artifacts |
Uploaded files (release filter) |
POST /projects/{p}/artifacts |
Multipart, fields in this order: kind (sourcemap|proguard|native; dSYMs, ELF and PDB are native), release (required except for native, which is matched by debug id), name (for source maps: URL path of the minified file, e.g. /assets/app.js), then file. Max 1 GB |
DELETE /projects/{p}/artifacts/{id} |
Delete |
The CLI wraps these; prefer vaka upload ... in build scripts.
Privacy
| Method & path | Description |
|---|---|
DELETE /projects/{p}/users/{user_id} |
Delete all errors, events and sessions for a user id (write scope). Returns counts. Cannot be undone |
Alerts
| Method & path | Description |
|---|---|
GET /alert-rules |
Rules, plus the valid triggers and channels |
POST /alert-rules |
See alerts |
PATCH /alert-rules/{id} / DELETE /alert-rules/{id} |
Update or delete |
POST /alert-rules/{id}/test |
Send a test notification |
GET /alert-rules/{id}/deliveries |
Recent deliveries and their status |
Tokens and users (admins)
| Method & path | Description |
|---|---|
GET /tokens, POST /tokens |
Create: {"name", "project"?, "scope": "read"|"write", "expires_in_days"?}. The token is returned once |
DELETE /tokens/{id} |
Revoke |
GET /users |
Users |
POST /users/invite |
{"email", "role": "viewer"|"member"|"admin"|"owner"}; returns an invite link (also emailed if Resend is set up) |
PATCH /users/{id} / DELETE /users/{id} |
{"role"?, "disabled"?} |
Roles: viewer reads everything, member can also triage issues and upload debug files, admin manages projects, tokens, users and alerts, owner is an admin who can manage other owners.