Developer docs
Running your program
Everything you need to set up domain verification, embed canary tokens, understand how auto-reproduction works, and configure your payout tiers.
Domain Verification
Before your program can go public, VibeBounty verifies that you control the domain you're listing. This prevents anyone from listing a program for a site they don't own.
How it works
Your product dashboard shows a unique verification token — a 32-character hex string. You need to make that token available at a specific URL on your site, then click Verify ownership in the dashboard. VibeBounty will fetch the URL and compare the file contents to your token.
Step 1 — Create the verification file
Create a plain-text file with your token as the sole contents (no surrounding whitespace, no newline):
vb-verify-a1b2c3d4e5f6... ← paste your exact token hereServe it at the exact path below, where yourdomain.com is the root of the website URL you entered for the product:
https://yourdomain.com/.well-known/vibebounty-verification.txtStep 2 — Confirm the file is reachable
The file must return HTTP 200 with the token as the body — no redirects, no HTML wrapper. VibeBounty fetches it with the user-agent VibeBounty-Ownership-Check. If your host blocks unknown user-agents, you may need to allowlist it.
Step 3 — Click Verify ownership
Go to your product in the developer dashboard and click Verify ownership. If the check passes, the product moves to verified status and you can enable the public listing.
pending and you must re-verify the new domain before re-enabling the listing.Hosting platform examples
| Platform | Where to add the file |
|---|---|
| Vercel | Put the file in public/.well-known/vibebounty-verification.txt — Vercel serves the public/ directory at the root. |
| Netlify | Same as Vercel — add to the public/ (or root) folder in your repo. |
| Cloudflare Pages | Add to the public/ output directory or the root of your dist folder. |
| GitHub Pages | Add the file directly to the repository root or docs/ folder at .well-known/vibebounty-verification.txt. |
| Custom server | Serve the file as a static asset at the /.well-known/ path, or add a route that returns the token string. |
Canary Tokens
Canary tokens prove that a researcher actually visited your site before submitting a report — not just guessed at a vulnerability from the outside. When enabled, every submission must include a verified canary hit or it is blocked.
How the canary works
When a researcher opens your program page, VibeBounty issues them a unique session token (stored in a vb_session cookie and URL query parameter). When they visit your site, a lightweight JavaScript snippet reads that token and sends a silent beacon back to VibeBounty. When they later submit a report, VibeBounty checks whether that token was seen on your domain — if it wasn't, the report is rejected automatically.
Adding the snippet
Copy the snippet from your product's settings in the developer dashboard — it includes the correct worker URL and your product ID pre-filled. It looks like this:
<script
src="http://localhost:3000/api/canary/script"
data-program="[your-product-id]"
async
></script>Add this tag to every page of your site that a researcher might visit while testing — ideally your root layout or _document. The script is under 1 KB, loads asynchronously, and does nothing if there is no active VibeBounty session.
vb_session cookie and the vb_session query parameter. Cookies require your site to be served over HTTPS.What the script collects
The beacon records: the canary token, the current page URL, the referrer, and the browser user-agent. No personal data beyond what the researcher's browser naturally sends is transmitted. The data is only used to verify that the session token was seen on your domain.
Making canary required
In your product settings, toggle Require canary proof. When this is on, any report submitted without a verified canary hit is automatically rejected before it reaches your inbox. This is the strongest protection against fabricated reports — we recommend enabling it for all production programs.
Verifying the snippet is working
In your developer dashboard, each product shows a Canary last seen timestamp. If you visit your own site with an active VibeBounty session, the timestamp will update within a few seconds. If it stays empty, check that the script tag is present and that HTTPS is enabled on your site.
Auto-Reproduction
Every submitted report is automatically tested by VibeBounty's reproducer before it reaches your inbox. It attempts to reproduce the vulnerability using the exact parameters the researcher provided — target URL, HTTP method, headers, body, and a verifiable response indicator. Reports that can't be reproduced are rejected automatically.
Reproduction modes
VibeBounty selects the reproduction mode based on the response indicator type:
| Mode | When used | What it does |
|---|---|---|
| HTTP | status_code, response_body, response_header | Makes a real HTTP request with the submitted method, headers, and body. Matches the response against the indicator. |
| Browser | dom_element, network_request | Launches a headless Chromium instance, navigates to the target URL, and checks for a matching DOM element or network request. |
Response indicator types
Researchers must select an indicator type when submitting. This is what the reproducer uses to decide whether the report is valid:
| Indicator type | Value format | Passes when |
|---|---|---|
| status_code | 200 | HTTP response status matches exactly. |
| response_body | any substring | Response body contains the substring (case-sensitive). |
| response_header | header-name: value | Header is present and its value contains the expected string. Omit the value to check presence only. |
| dom_element | CSS selector | Browser finds at least one element matching the selector after page load. |
| network_request | URL substring | Browser observes a network request whose URL contains the substring. |
| timing | — | Not automatically reproduced. Reported as inconclusive — manual review required. |
| other | — | Not automatically reproduced. Reported as inconclusive — manual review required. |
The reproducer user-agent
HTTP-mode requests are sent with the user-agent:
VibeBounty-Reproducer/1.0 (+https://vibebounty.dev/bot)You may see this in your access logs after a report is submitted. Do not block this user-agent — doing so will cause all reports against your program to fail reproduction and be auto-rejected.
Reproduction status lifecycle
| Status | Meaning |
|---|---|
| pending | Report received. Queued for reproduction. |
| running | The reproducer has claimed the job and is actively testing. |
| reproduced | The indicator matched. Report is forwarded to your inbox as verified. |
| failed | The indicator did not match. Report is auto-rejected as unreproducible. |
| skipped | Indicator type cannot be automatically tested (timing, other). Forwarded to your inbox for manual review. |
| error | The reproducer hit an unexpected error and will retry automatically. |
Auto-close on inactivity
Open reports with no developer action are automatically closed after 14 days of inactivity. The close reason is auto_closed_stale and the researcher is not penalised. To prevent auto-close, add a comment or change the status before the deadline.
Reproduction attempts
Failed or errored reproductions are automatically retried. If all attempts fail, the report is marked failed and auto-rejected. Transient network errors consume an attempt but do not immediately mark the report as failed.
Test Credentials
If your program requires authentication to reach the pages a researcher would test, you can provide test credentials in your product settings. The reproducer uses them to log in before attempting to verify a report — without them, any vulnerability behind a login wall will fail reproduction.
Adding credentials
In your product settings, enter a login URL, username, and password for a dedicated test account on your site. Credentials are stored encrypted and are only accessed by the automated reproducer — they are never visible to researchers.
When credentials are used
Credentials apply to browser-mode reproductions (dom_element, network_request indicator types). If no credentials are provided, the reproducer tests the target URL directly without authentication.
Severity Guide
Severity is set by the researcher at submission time and follows a standard rubric. You can dispute the severity in the report thread, but you cannot unilaterally downgrade a finding to avoid a payout — the original severity is locked unless both parties agree.
Your payout tiers (P1–P5) are set per-product in the dashboard. Set them to amounts you can sustain — researchers filter programs by bounty range.
| Severity | Label | Typical findings |
|---|---|---|
| P1 | Critical | Remote code execution (RCE), authentication bypass, payment manipulation, full account takeover, mass data exposure. |
| P2 | High | SQL injection, SSRF with internal access, privilege escalation, stored XSS with high-privilege targets, significant data exfiltration. |
| P3 | Medium | IDOR with meaningful data access, stored XSS with user impact, CSRF with state-changing effect, partial auth bypass. |
| P4 | Low | Reflected XSS, low-impact information disclosure, rate limiting bypass, open redirect, session fixation. |
| P5 | Informational | Best-practice violations, missing security headers, low-risk misconfigurations, theoretical issues with no demonstrated impact. |
Payout Process
Developers pay the listed bounty when they accept a report. Researchers receive the bounty net of the estimated Stripe processing fee reserve. We charge developers a flat monthly subscription to run programs.
Accepting a report
When you accept a report, VibeBounty immediately creates a payout record and initiates a Stripe transfer to the researcher's connected Stripe account. The transfer typically settles within 1–2 business days depending on the researcher's bank.
You need sufficient balance in your Stripe account to cover the transfer. If the transfer fails, the payout will show as failed in your dashboard — you can retry it manually or contact the researcher to sort out their Stripe connection.
Rejecting a report
Rejected reports require a reviewer note explaining why. Valid rejection reasons:
| Reason | Description |
|---|---|
| rejected_invalid | The vulnerability doesn't exist or the report is factually wrong. |
| rejected_duplicate | A report for the same issue has already been submitted. |
| rejected_out_of_scope | The target or technique is outside the program scope. |
| rejected_unreproducible | You cannot reproduce the issue following the provided steps. |
| rejected_canary_violation | The researcher used the canary token in a way that violates program rules. |
Include a reviewer note explaining your reasoning. The note is visible to the researcher.
Researcher Stripe requirements
Researchers must connect a Stripe account before they can receive a payout. If you accept a report but the researcher has no connected account, the payout will be held until they connect one. You won't be charged until the transfer is issued.