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):

Content of .well-known/vibebounty-verification.txt
vb-verify-a1b2c3d4e5f6...  ← paste your exact token here

Serve it at the exact path below, where yourdomain.com is the root of the website URL you entered for the product:

Required URL
https://yourdomain.com/.well-known/vibebounty-verification.txt

Step 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.

The token must match exactly. A trailing newline or extra space will fail the check. Most static hosts serve plain text files correctly — check your hosting panel if you're unsure.

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.

If you change your product's website URL later, ownership reverts to pending and you must re-verify the new domain before re-enabling the listing.

Hosting platform examples

PlatformWhere to add the file
VercelPut the file in public/.well-known/vibebounty-verification.txt — Vercel serves the public/ directory at the root.
NetlifySame as Vercel — add to the public/ (or root) folder in your repo.
Cloudflare PagesAdd to the public/ output directory or the root of your dist folder.
GitHub PagesAdd the file directly to the repository root or docs/ folder at .well-known/vibebounty-verification.txt.
Custom serverServe 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:

HTML — add before </body>
<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.

The script reads the 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.

If you require canary proof but haven't added the snippet to your site, legitimate researchers will be blocked too. Confirm the snippet is loading correctly (open your site in an incognito window with a test session) before toggling it on.

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:

ModeWhen usedWhat it does
HTTPstatus_code, response_body, response_headerMakes a real HTTP request with the submitted method, headers, and body. Matches the response against the indicator.
Browserdom_element, network_requestLaunches 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 typeValue formatPasses when
status_code200HTTP response status matches exactly.
response_bodyany substringResponse body contains the substring (case-sensitive).
response_headerheader-name: valueHeader is present and its value contains the expected string. Omit the value to check presence only.
dom_elementCSS selectorBrowser finds at least one element matching the selector after page load.
network_requestURL substringBrowser observes a network request whose URL contains the substring.
timingNot automatically reproduced. Reported as inconclusive — manual review required.
otherNot 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

StatusMeaning
pendingReport received. Queued for reproduction.
runningThe reproducer has claimed the job and is actively testing.
reproducedThe indicator matched. Report is forwarded to your inbox as verified.
failedThe indicator did not match. Report is auto-rejected as unreproducible.
skippedIndicator type cannot be automatically tested (timing, other). Forwarded to your inbox for manual review.
errorThe 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.

Use a dedicated test account with minimal permissions. Do not provide admin or production credentials. The reproducer will log in automatically on every reproduction attempt.

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.

SeverityLabelTypical findings
P1CriticalRemote code execution (RCE), authentication bypass, payment manipulation, full account takeover, mass data exposure.
P2HighSQL injection, SSRF with internal access, privilege escalation, stored XSS with high-privilege targets, significant data exfiltration.
P3MediumIDOR with meaningful data access, stored XSS with user impact, CSRF with state-changing effect, partial auth bypass.
P4LowReflected XSS, low-impact information disclosure, rate limiting bypass, open redirect, session fixation.
P5InformationalBest-practice violations, missing security headers, low-risk misconfigurations, theoretical issues with no demonstrated impact.
Researchers are required to select the lowest severity that accurately describes the impact. Inflate severity deliberately and your account can be flagged for a strike. If you believe a severity is wrong, start a conversation in the report thread.

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:

ReasonDescription
rejected_invalidThe vulnerability doesn't exist or the report is factually wrong.
rejected_duplicateA report for the same issue has already been submitted.
rejected_out_of_scopeThe target or technique is outside the program scope.
rejected_unreproducibleYou cannot reproduce the issue following the provided steps.
rejected_canary_violationThe 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.

Questions not covered here? Contact support →