The platform is built on a REST API at https://api.rootbounty.com/v1. The full, generated reference is at /reference.
From the internet, the API accepts personal API keys only (below). You cannot sign in, create or delete an account, or manage security through the API: that is done on the website. Nothing is served without a valid key.
The website's own server uses the same API over a private network (a client credential plus the visitor's session token). Those endpoints are not reachable through api.rootbounty.com and are not part of the reference: the reference lists exactly what a key can call.
The staff API is a separate service on a private network and is not documented publicly.
Researchers and companies can use the API from their own scripts. Create a key in Settings → API keys (you need your password), then call api.rootbounty.com directly:
curl -H "Authorization: Bearer rbp_…" https://api.rootbounty.com/v1/me/reports
POST /v1/programs/{handle}/reports), with the same fields as the form on the site: title, asset in scope, CWE, CVSS 4.0 vector, description, impact, environment and proof of concept. Attachments are added on the website.x-personal-key-scope in the API reference.Retry-After: 60.Every endpoint below is a GET and answers with what your account would see on the website.
| Endpoint | What it lists |
|---|---|
/v1/me |
Your account summary |
/v1/programs, /v1/programs/{handle} |
Programs you can see (public ones and private ones you were invited to), with scope and rewards |
/v1/hacktivity, /v1/programs/{handle}/hacktivity, /v1/hacktivity/reports/{number} |
Public activity and disclosed reports |
/v1/leaderboard, /v1/profiles/{username} |
Reputation ranking and public profiles |
/v1/posts, /v1/suggestions, /v1/jobs, /v1/jobs/{id} |
Community posts, suggestions and job offers |
/v1/me/reports, /v1/reports/{number} |
Researchers: the reports you sent and their timeline |
/v1/me/invitations, /v1/me/payouts, /v1/me/notifications, /v1/me/community |
Researchers: invitations, earnings, notifications, progress towards posting |
/v1/company/reports, /v1/company/programs, /v1/company/jobs, /v1/company/payouts |
Companies: inbox, programs (and their invitations), job offers and bounties paid |
The only thing a key can create. It needs a researcher's key with Read and submit reports access.
GET /v1/programs/{handle} returns scope[]; take the id of an entry with inScope: true.curl -X POST https://api.rootbounty.com/v1/programs/acme-payments/reports \
-H "Authorization: Bearer rbp_…" \
-H "Content-Type: application/json" \
-d '{
"title": "Stored XSS in the invoice notes field",
"scopeItemId": "s1",
"cweId": 79,
"cvssVector": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N",
"description": "The notes field of an invoice is rendered without escaping in the customer portal…",
"impact": "An attacker with a customer account can run scripts in the session of staff who open the invoice.",
"environment": "Chrome 153, production, two test accounts of my own.",
"poc": "1. Create an invoice… 2. Put the payload in the notes… 3. Open it as another user…"
}'
| Field | Rules |
|---|---|
title |
10–200 characters |
scopeItemId |
id of an in-scope asset of that program |
cweId |
CWE number, e.g. 79 |
cvssVector |
Complete CVSS 4.0 base vector; the score and severity are computed by RootBounty |
description |
Markdown, at least 40 characters |
impact |
Markdown, at least 20 characters |
environment |
Markdown, at least 3 characters |
poc |
Markdown, at least 20 characters |
The answer is 201 with the new report (its number, status new) and a Location header. Invalid fields answer 422 with one entry per field in errors[]. Attachments, comments and everything that follows happen on the website. See Writing a good report for what to put in each field.
| You try | Answer |
|---|---|
| Any request without a valid key | 401 invalid_client / invalid_api_key |
Signing in, creating or deleting an account, or any other POST, PUT, PATCH or DELETE |
403 read_only |
| Submitting a report with a read-only key | 403 insufficient_scope |
An endpoint your role can't use (e.g. a researcher on /v1/company/…) |
403 forbidden_role |
| A sixth request within the same minute | 429 rate_limited, Retry-After: 60 |
GET collections accept ?page=&perPage= (max 100) and return:
{ "data": [ … ], "meta": { "page": 1, "perPage": 25, "total": 330, "totalPages": 14 } }
with Link (first, prev, next, last) and X-Total-Count headers.
Errors are RFC 9457 problem details (application/problem+json):
{
"type": "about:blank",
"title": "Validation failed",
"status": 422,
"detail": "Title: 10–200 characters.",
"errors": [{ "field": "title", "message": "Title: 10–200 characters." }],
"requestId": "…"
}
Machine-readable reasons come in code (for example invalid_client, account_pending_approval, posting_locked, rate_limited). Quote requestId when contacting support.
API keys: 5 requests per minute per account. New reports are also limited per day. Limited calls answer 429 with a Retry-After header.