Overview
Bugnet exposes the same REST API the dashboard uses, so you can build custom integrations, automate triage, and manage projects programmatically. There are two ways in:
- Public API — what a game client or public web page calls: bug submission, sessions, telemetry, and the public tracker, roadmap and changelog. Authenticated with the project API key, or not at all.
- REST API — everything a team member can do in the dashboard. Authenticated with a user session token.
- Base URL:
https://api.bugnet.io(paths below start with/api/).https://bugnet.io/api/…reaches the same API. - Versioned paths: every
/api/…route is also served under/api/v1/…. Pin to/api/v1/in long-lived integrations. - Request and response bodies are JSON (UTF-8) unless an endpoint says it takes a file upload.
- Projects are addressed by slug. Bug reports are addressed by their per-project report number (the
#12in the dashboard), not their UUID —:numberbelow.
Prefer an interactive reference? The API Explorer renders Bugnet’s OpenAPI specs with full request and response schemas, and lets you send test requests. Download the specs directly: public.yaml (SDK & public endpoints) and rest.yaml (core REST resources).
# Example: list your projects
curl https://api.bugnet.io/api/projects \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"Authentication
Which credential an endpoint takes depends on who is calling it.
Session token (REST API)
Sign in with POST /api/auth/login (email and password) to get a session token, then send it on every request. Tokens last 30 days; POST /api/auth/logout revokes one early. A session token acts as that user on every project in their account, so keep it on a server.
Authorization: Bearer YOUR_SESSION_TOKENProject API key (SDK / Public API)
Game clients authenticate with the project’s API key (sk_live_…), shown on the project’s Integrate tab and rotated with POST /api/projects/:slug/rotate-key. Most SDK endpoints take it in a header:
X-API-Key: sk_live_YOUR_PROJECT_KEYThe two session endpoints (/api/sessions/start and /api/sessions/end) take it as api_key in the JSON body instead. An API key is accepted only while the project’s Public setting (is_public) is on, which is the default; turning it off makes every SDK call fail with 401 invalid API key.
Never ship a session token in a game build. The API key can only file reports and telemetry into one project; a session token can read and change everything its user can.
Rate Limits
Limits are counted per client IP over a one-minute window. Every request counts toward the global budget; some routes also have their own, tighter budget, and whichever runs out first applies.
| Applies to | Limit |
|---|---|
| Every request (global) | 300 requests/minute |
| Public & SDK endpoints (bug submit, sessions, events, tracker, roadmap, changelog, branding, files) | 30 requests/minute |
/api/perf/snapshot and /api/session-replays | 120 requests/minute |
| Login, signup and resend-verification | 10 requests/minute |
Responses carry the budget that applied:
X-RateLimit-Limit— requests allowed in the windowX-RateLimit-Remaining— requests left in the windowX-RateLimit-Reset— Unix time (seconds) the window resets
Past the limit the API returns 429 Too Many Requests with a Retry-After header (seconds). Wait that long before retrying.
Response Format
Every JSON response uses the same envelope, with an ok boolean saying whether the request succeeded.
Success Response
{
"ok": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"report_number": 42
}
}Error Response
{
"ok": false,
"error": "title and description are required"
}Common HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success (also returned when a submitted report was stacked onto an existing one) |
201 | Created |
400 | Bad request — malformed JSON or a validation error |
401 | Missing or invalid session token or API key |
403 | You lack the permission, the feature isn’t on your plan, or a plan limit is reached |
404 | Not found — also returned for projects you are not a member of |
409 | Conflict (e.g. email already registered, label already exists) |
429 | Rate limited |
500 | Server error |
Enumerations
| Field | Values |
|---|---|
status | open, in_progress, resolved, closed, wont_fix |
priority | critical, high, medium, low |
category | crash, visual, gameplay, performance, audio, ui, network, other |
SDK Endpoints
Called from inside your game. All use the project API key. Full schemas are in the Public API explorer.
Bug reports
Submit a bug report. Requires title and description; optional priority, category, platform, game_version, os_info, device_info, steps_to_reproduce, expected_behavior, actual_behavior, screenshot (base64), steam_id, reporter_name, reporter_email, metadata (any JSON, ≤16 KB), attachments (up to 10 base64 files), auto_captured. Returns 201 with the new report, or 200 with deduplicated: true when grouping stacked it onto an existing report with the same title. Body limit 20 MB.
Attach one file to a report you just submitted, using the id from the submit response. Body: {filename, mime_type, data} with base64 data. Text, image, video and JSON only, ≤10 MB.
The project’s SDK settings: screenshot capture, session capture (Studio Plus only), auto-filing of errors, editor-error and warning capture, and the in-game widget theme.
Example: submit a bug report
curl -X POST https://api.bugnet.io/api/bugs/submit \
-H "X-API-Key: sk_live_YOUR_PROJECT_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Player falls through floor on level 3",
"description": "Near the bridge the collision mesh has a gap.",
"category": "gameplay",
"priority": "high",
"platform": "Windows",
"game_version": "1.2.0",
"steps_to_reproduce": "1. Start level 3\n2. Walk to the bridge\n3. Jump near the left railing"
}'{
"ok": true,
"data": {
"id": "0b6e3f5c-8a1d-4f2e-9c47-5d3a2b1e0f98",
"report_number": 42,
"message": "Bug report submitted successfully!",
"category": "gameplay",
"priority": "high",
"sentiment_score": 0,
"sentiment_level": "calm",
"possible_duplicates": [17]
}
}Sessions
Start a play session. Body: {api_key, session_token, platform, game_version, device_info, os_info, steam_id, player_name} — api_key and a client-generated session_token are required. Returns 409 if the token was already used.
End a session. Body: {api_key, session_token, crashed}. Sessions ending with crashed: true lower the crash-free rate.
Telemetry
Track one custom event. Body: event_name (required, ≤100 chars), event_data (JSON object, ≤4 KB), session_token, platform, game_version. Studio and Studio Plus only.
Track 1–50 events in one request. Body: {events: [...]}, each shaped like a single event.
Attach performance metrics to a report. Body: bug_report_id (required) plus any of fps, frame_time_ms, memory_used_mb, memory_total_mb, draw_calls, triangles, cpu_usage, gpu_usage, load_time_sec, network_latency_ms, custom_metrics (string).
Upload a session recording for a report as multipart/form-data: bug_report_id, file (WebM, MP4 or GIF), optional duration_sec and metadata. Studio Plus only.
Public Endpoints
No authentication. These power the public tracker, roadmap and changelog, and are safe to call from any web page.
Public tracker
Public bug list, 25 per page, most-upvoted first. Query: status, category, q (search, if the tracker allows it), page. 404 unless the tracker is enabled.
One public bug with its non-internal comments.
Upvote a bug. Optional body {player_id}; without it the voter is identified by IP. One vote per voter — repeats return the current count with is_new: false.
Public roadmap
Roadmap settings and the bugs in the statuses the roadmap shows. 404 unless the roadmap is enabled.
Upvote a roadmap item. Same rules as the tracker vote; 403 unless the roadmap shows upvotes.
Changelog, branding and files
Up to 50 published changelog entries, newest first.
Public branding: logo, colors, company name, support email.
Download an uploaded screenshot, attachment or replay. Use the file_url / screenshot_url values returned elsewhere — they already include this prefix.
Status
Health check at the API root (not under /api). Returns {"status": "healthy"} with 200, or 503 when the database is unreachable. Not wrapped in the response envelope.
The maintenance banner currently in effect, if any.
Example: health check
curl https://api.bugnet.io/health{"status":"healthy"}Auth Endpoints
Sign in, manage the signed-in user, and export or delete their data.
Create an account and sign in. Body: {name, email, password} — password at least 8 characters. Returns 409 if the email is taken.
Sign in. Body: {email, password}. Returns a session token.
Revoke the session token used for this request.
The signed-in user’s profile.
Update your profile. Body (any of): {display_name, avatar_url, theme, role}.
Change password. Body: {current_password, new_password}. Email/password accounts only.
Create a temporary code you can give Bugnet support so they can find your account. Query: hours (1, 3 or 24; default 1).
Revoke your support share code.
Download your profile, projects, reports and comments as JSON.
Permanently delete your account and cancel any subscription you pay for. Body: {"confirmation": "DELETE"}.
Verify an email address. Query: token (from the verification email).
Resend the verification email.
Example: sign in
curl -X POST https://api.bugnet.io/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "dev@example.com", "password": "your_password"}'{
"ok": true,
"data": {
"token": "3f9a1c...",
"user_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "dev@example.com",
"name": "Dev",
"onboarding_done": true,
"email_verified": true
}
}Project Endpoints
Projects belong to your account. You see every project in the account you work in.
List your projects with bug counts.
Create a project. Body: {name, slug, description, website_url} — only name is required. The stored slug gets a short prefix to keep it unique (e.g. a1b2c3-my-game), so use the slug in the response. Also returns the new api_key.
Project details, SDK settings, API key, stats and your role.
Update a project. Body (any of): name, description, website_url, logo_url, is_public, screenshot_capture, session_capture, auto_file_errors, capture_editor_errors, capture_warnings, bug_grouping.
Delete a project and its reports. Account owner (or the teammate who created it) only.
Issue a new API key. The old key stops working immediately.
Whether the SDK has sent its first report, session and so on (drives the onboarding checklist).
File a sample report to check your integration end to end.
Example: create a project
curl -X POST https://api.bugnet.io/api/projects \
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "My Cool Game",
"slug": "my-cool-game",
"description": "An awesome platformer",
"website_url": "https://mycoolga.me"
}'Bug Endpoints
Manage reports inside a project. :number is the report number, not the UUID. To file reports from a game, use POST /api/bugs/submit above.
Reports
List reports, 25 per page. Query: status, priority, category, q (full-text search), assigned_to (user ID or unassigned), label (label ID), source (user or system), error_type (an exception/error class such as NullReferenceException), sort (priority, upvotes, updated; default newest), page.
Create a report as yourself. Body: title and description (required), priority, category, platform, game_version, os_info, device_info, steps_to_reproduce, expected_behavior, actual_behavior.
A report with its comments and labels.
The exception/error classes found in the project’s reports, each with a report count, most common first: [{error_type, count}]. Every report’s error_type is read from its title and stack trace (e.g. NullReferenceException, TypeError, ZeroDivisionError, SIGSEGV), and is empty when it names none.
Update a report. Body (any of): title, description, status, priority, category, assigned_to (needs bugs.assign), is_private, platform.
Delete a report. Deleted reports still count toward your plan’s report quota.
Update up to 100 reports. Body: bug_ids or bug_numbers, plus any of status, priority, category, assigned_to, is_private.
Delete up to 100 reports. Body: bug_ids or bug_numbers.
Find reports similar to a title. Query: title.
Download reports as CSV. Query: status, priority.
Comments, activity and attachments
Add a comment. Body: {body, is_internal}. Internal comments never appear on the public tracker.
The report’s activity log.
List attachments.
Upload an attachment as multipart/form-data field file (≤10 MB; text, image, video or JSON).
Recent activity across the project. Query: action to filter by action type.
Project audit log of settings, label, member and integration changes. Query: page.
Grouping and occurrences
The individual submissions stacked onto this report, 50 per page. Query: page.
Split selected occurrences off into their own report.
Dependencies, due dates and custom fields
Reports this one blocks or is blocked by.
Link two reports. Body: {related_number, relationship} where relationship is blocks or blocked_by.
Remove a dependency link.
Set or clear a due date. Body: {due_date} (null clears it).
Custom field values for a report.
Set a custom field value. Body: {field_id, value}.
Example: list open high-priority reports
curl "https://api.bugnet.io/api/projects/my-cool-game/bugs?status=open&priority=high&sort=updated&page=1" \
-H "Authorization: Bearer YOUR_SESSION_TOKEN"Example: resolve a report
curl -X PATCH https://api.bugnet.io/api/projects/my-cool-game/bugs/42 \
-H "Authorization: Bearer YOUR_SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "resolved"}'Labels & Organization
Labels, templates, custom fields, SLA rules, saved filters and saved views.
Labels
List labels.
Create a label. Body: {name, color} (color defaults to #2E5BFF).
Rename or recolor a label. Body: {name, color}.
Delete a label and remove it from every report.
Apply a label. Body: {label_id}.
Remove a label from a report.
Templates and custom fields
List bug templates.
Create a template. Body: {name, description, priority, category, body_template}.
Update a template.
Delete a template.
List custom field definitions.
Define a custom field. Body: {name, field_type, options, is_required}.
Delete a custom field.
SLA rules
Response and resolution targets per priority.
Replace the SLA rules. Body: {rules: [{priority, response_hours, resolve_hours}]}.
Saved filters and views
Your saved filters.
Save a filter. Body: {name, project_id, filters}.
Delete a saved filter.
Your saved views.
Save a view. Body: {name, project_id, filters, sort_by, pinned}.
Update a view (including position for ordering).
Delete a saved view.
Import
Bulk-import reports from another tracker. Body: {bugs: [{title, description, status, priority, category, platform, game_version, steps_to_reproduce, external_id, external_url, source}]}.
Previously imported reports and where they came from.
Account & Team Endpoints
Your team is a roster on your account, and the account owns every project on it. One invitation gives someone the whole account; removing them takes all of it away. The project-scoped routes further down are views onto the same roster.
The account you work in: name, your role, plan, members, pending invitations, projects, usage and limits.
Rename the account. Body: {name}. Owner or admin only.
List the account roster and any pending invitations.
Change a member’s role across the whole account. Body: {role} — admin or member.
Remove a member from the account and from every project on it. Passing your own user ID leaves the account.
Invite someone to the account. Body: {email, role}. Returns the invitation token. Counts toward your plan’s seat limit.
Accept an invitation. Body: {token}.
Revoke a pending invitation.
The project-scoped equivalents act on the account that project belongs to: GET /api/projects/:slug/members, PATCH and DELETE /api/projects/:slug/members/:userId, POST /api/projects/:slug/invites, DELETE /api/projects/:slug/invites/:inviteId, and POST /api/invites/accept.
Permissions
Permissions are set per member on the account and apply to every project in it. The project-scoped routes GET /api/projects/:slug/permissions and GET/PUT/DELETE /api/projects/:slug/permissions/:userId act on the same account-wide overrides.
Your effective permissions in the account you work in.
The permission catalog: groups, keys and each role’s defaults.
A member’s effective permissions and overrides.
Grant or revoke permissions for a member. Body: permissions (key → true/false), groups (group → true/false), reset (drop existing overrides first). Needs team.permissions; owners are never edited and only the owner edits an admin.
Reset a member to their role defaults.
Analytics Endpoints
Dashboard analytics, crash data, release health, performance, regressions, satisfaction, players and events. All take a session token.
Dashboard and usage
Cross-project analytics for the signed-in user: reports by status, priority and category, and trends.
Report and session volume for each of your projects (today, 7 and 30 days).
The same usage figures for one project.
Crashes and release health
Crash-free session rate and its 30-day trend, top crash signatures, platform breakdown.
Compares the crash rate of the two newest game versions (each with at least 10 sessions) to flag a bad release.
Crash reports clustered by signature. Studio and up.
Health score, grade and crash-free rate for each game version.
Drill-down for one version. Query: version.
Regressions and triage
Find new reports that look like previously resolved ones.
Regressions that have been confirmed or dismissed.
Confirm or dismiss a detected regression. Body: {original_bug_id, new_bug_id, status, resolved_version, regressed_version} with status confirmed or dismissed.
Auto-triage suggestions for one report. Studio and up.
Players whose recent reports suggest they may stop playing. Studio and up.
Performance and replays
The performance snapshot captured with a report.
Project-wide performance averages.
Session replays attached to a report (Studio Plus).
Satisfaction
Rate how a report was handled. Body: {rating, comment} with rating 1–5.
The rating for one report.
Rating distribution, monthly trend and per-category averages.
Players
Players seen through sessions and reports.
One player’s profile.
Update a player’s notes and sentiment. Body: {notes, sentiment} with sentiment positive, neutral or negative.
A player’s sessions.
Reports linked to a player.
Player totals and contact overview.
Events and live logs
Studio+Event names with counts and unique sessions. Query: days (1–90, default 30).
Daily volume and the top 5 events. Query: days.
One event’s daily trend, platform breakdown and last 50 raw events. Query: days.
A reverse-chronological feed of events, reports and team activity. Query: days (1, 7, 30 or 90), page. Studio plan and up; returns 403 on the free plan.
Integration Endpoints
Webhooks, Slack, Microsoft Teams, PagerDuty, Opsgenie, Sentry, Linear, ClickUp, Jira, Asana, Trello, Airtable, monday.com, Notion, Google Play, App Store, Discord, GitHub/GitLab, Steam, alerts and notifications. See Integrations for payloads and setup.
Webhooks
List webhooks.
Create a webhook. Body: {url, name, event_types, secret} — event_types is a comma-separated string (default bug_created,bug_updated,comment_added).
Delete a webhook.
Send a test payload and report the receiver’s HTTP status.
Recorded deliveries for a webhook.
Slack, Microsoft Teams, Linear, ClickUp & other providers
One set of routes for every provider; :provider is slack, teams, pagerduty, opsgenie, sentry, linear, clickup, jira, asana, trello, airtable, monday, notion, googleplay or appstore. Writes need the project.integrations permission.
Providers a project can connect to, with the events each accepts.
List the project’s connections. Query: provider. Credentials are never returned; secret_hint identifies each one.
Connect. Body: {secret, name, event_types, min_priority, config} — secret is the Slack incoming webhook or Teams Workflows URL, the Linear API key or the ClickUp API token; config is {team_id} for Linear and {list_id} for ClickUp; event_types is an array of bug_created, bug_updated, comment_added, digest (trackers take the first two).
Where a tracker can file: Linear teams, ClickUp/Trello lists, Jira/Asana/Sentry projects, Airtable tables, monday.com boards, Notion databases. Body: {secret, config}, or {id} of a saved connection.
Change any of name, secret, event_types, min_priority, is_active.
Disconnect.
Send a test message (chat) or check the key and team/list still work (trackers); 502 with the tool’s answer if it is rejected.
The connection’s 50 most recent messages and their delivery status.
Google Play / App Store: import reviews now (otherwise hourly). Returns {fetched, new, filed}.
Imported store reviews, newest first. Query: provider, max_rating, page (50 per page).
Post or replace the public developer reply. Body: {body}. Google Play allows 350 characters.
Issues trackers filed for a report (links) and the tracker connections that could file it (trackers).
File a report in a tracker now. Body: {integration_id}. Filing it again through the same connection returns the existing issue.
Discord
List Discord channels.
Add a Discord webhook. Body: {webhook_url, channel_name, event_types}.
Update it. Body (any of): webhook_url, channel_name, event_types, is_active.
Remove it.
Post a test message to the channel.
Git (GitHub / GitLab)
The connected repository.
Connect a repository. Body: {provider, repo_url, access_token} with provider github or gitlab.
Update it. Body: {auto_create_issues, access_token}.
Disconnect the repository.
Search the repository’s issues. Query: q.
Create an issue in the connected repository from a report, or link an existing one with {issue_number, issue_url, issue_title}.
The issue linked to a report.
Steam
The connected Steam app.
Connect a Steam app. Body: {app_id}.
Update it. Body: {sync_enabled}.
Disconnect Steam.
Fetch new reviews now.
Review sentiment and recent reviews.
List synced reviews.
Positive and negative reviews over time.
Reviews that suggest a refund.
Sync run history.
Alerts and notifications
List alert rules.
Create an alert rule. Body: {metric, threshold, window_hours}.
Update a rule. Body (any of): threshold, window_hours, enabled.
Delete a rule.
Your email notification preferences.
Update them. Body: {email_bug_created, email_bug_status, email_bug_assigned, email_bug_commented, email_weekly_digest}.
Public Page & Widget Settings
Configure what the public endpoints show.
Public tracker settings.
Update them: enabled, page_title, page_description, accent_color, logo_url, allow_search, allow_upvotes, show_categories, show_priority, show_status_filter, custom_css.
Public roadmap settings.
Update them.
Every changelog entry, drafts included.
Create an entry. Body: {title, body, version, publish}.
Update or publish an entry.
Delete an entry.
Draft an entry from recently resolved reports.
Branding settings.
Update branding.
In-game widget theme.
Update the widget theme (Studio and up).
Upload a widget background image.
Billing Endpoints
Plan, usage and payment management. See Billing API for details.
The account’s plan, usage and limits, plus a features map of which plan-gated features the account carries.
Start a Stripe Checkout session for a plan.
Confirm a completed checkout.
Open the Stripe customer portal.
Your invoices.
Saved payment methods.
Start adding a payment method.
Set the default payment method.
Remove a payment method.
Downgrade at the end of the billing period.
A scheduled downgrade, if any.
Cancel a scheduled downgrade.