# Pro API Reference — Endpoints, Examples & MCP | bbradar.io

> Complete reference for authentication, platform and Self-Hosted data, MCP-efficient polling, endpoints, examples, responses, limits, and errors.

Source: [https://bbradar.io/docs/api](https://bbradar.io/docs/api)

<a id="authentication"></a>

## Authentication

v1

Every Pro API request uses your personal API key as a Bearer token. Keep the key in a server-side secret or MCP client environment—never in browser JavaScript or a public repository.

Base URL

`https://bbradar.io/api`

Request header

`Authorization: Bearer YOUR_PRO_API_KEY`

The complete secret is displayed once. Regenerating it immediately invalidates the previous key.

[Manage API key](https://bbradar.io/account#api-key)

<a id="first-request"></a>

## Make your first request

Start with capabilities so automation can negotiate the current contract without scanning catalog data.

```
curl -sS "https://bbradar.io/api/v1/pro/capabilities" -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Invalid query or path parameters return `400` with a detail message and an errors array. Authentication failures return `401`; missing programs return `404`.

<a id="catalog-status"></a>

## Catalog status and field types

Program lists and exact detail include confirmed paused platform programs. Read `program_status` and `is_active` together: a paused program retains `is_active: false`. Its scope and reward information describe the last published state, and bounty eligibility is disabled. Global target search, opportunity lists, and change feeds require active programs. Exact target reads may return retained scope with the parent status attached; bulk exports include paused scope only with explicit program IDs and `include_ineligible=true`.

| Field | Type and meaning |
| --- | --- |
| program_status / is_active | String status and boolean lifecycle state. Paused platform metadata remains visible; paused does not mean active. |
| star_rating | Integer from 1 to 5, or null when the vote threshold is not met. |
| review_signal / weighted_sentiment | Numbers derived from recorded vote totals; these are not text review labels. |
| report_count | Number or null. Check report_count_source and report_count_label when present because platform reporting windows differ. |
| submission_cost | Object or null. Missing platform observations currently default to amount 0 with source missing_defaults_free; free-platform policy uses platform_policy. Neither default is a newly observed fee. |
| data_capabilities | Boolean markers for available catalog signals. A false capability means unsupported, not a measured zero. |

Examples use fictional programs and reserved example domains. Response examples are abbreviated; preserve unknown fields for forward compatibility. Identifiers use the exact `platform:handle` returned by the API, and handles can contain slashes.

<a id="data-fields"></a>

## Opportunity and Target Intelligence

Pro responses include structured signals that clients can display directly. Each field below has one job.

### Program opportunity

`opportunity_tag`Tier, score, factors, and the reason a program is highlighted.

`submission_cost`Amount, optional maximum, unit, fee or deposit type, source, and observation time.

### Target score

`targetOpportunityScore``targetOpportunityLabel`A 0–100 score and its fixed Elite, Strong, Potential, or Normal label.

`targetScoreBreakdown``whyThisTarget`The underlying factors and a concise human-readable explanation.

### Competition risk

`competitionRisk``competitionRiskReason`Low, Medium, High, or Unknown, plus the evidence behind that classification.

Higher means more crowded or duplicate-prone. Unknown means insufficient public data—not Low risk.

### Self-Hosted capability markers

Self-Hosted IDs use `Self-Hosted:program-slug`. Their `data_capabilities` object is authoritative: target inventory is returned, while report counts, opportunity scores, target-change history, submission costs, and repository changes are not invented when no source exists.

Target labels use fixed score bands: Elite Target is 85–100, Strong Target is 70–84, Potential Target is 50–69, and Normal is 0–49. Out-of-scope or explicitly ineligible targets do not receive Target Intelligence.

Use scoring model versions and evidence coverage in the returned breakdowns to interpret the available factors. Scores and competition labels are comparative estimates, not measured duplicate probabilities. Repository events include a `comparison` object describing evidence completeness, method, reason, matcher version, ancestry, and provider commit count when known. Target associations expose `match_quality` and `match_reason`; program summaries preserve `match_qualities`, including when `include_targets=false`. Unknown evidence remains unknown.

<a id="mcp-polling"></a>

## Efficient MCP polling

Use `after_id` for incremental feeds. Results are oldest-first; start with `after_id=0`, persist `meta.next_after_id` after processing the response, and send it with the next request. This skips total-count and facet work.

Target changes

```
curl -sS -G "https://bbradar.io/api/v1/pro/targets/changes" \
  --data-urlencode "after_id=48101" \
  --data-urlencode "page_size=50" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Repository summaries

```
curl -sS -G "https://bbradar.io/api/v1/pro/repositories/changes" \
  --data-urlencode "after_id=17041" \
  --data-urlencode "include_targets=false" \
  --data-urlencode "page_size=50" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Cursor mode requires `page=1`. Repository target-intelligence filters are page-only; indexed search, platform, tag, submission-cost, and visibility filters can be used with the cursor.

<a id="stable-pagination"></a>

## Stable pages and recovery

Ordinary page requests read live data. For stable pagination, send `snapshot=start` on page 1 of programs, target search, target changes, or repository changes. Reuse `meta.snapshot` on later pages with the same filters and account. Page size may change. Use `meta.snapshot_expires_at` and `meta.as_of` to track expiry and the observation cutoff.

Snapshot response metadata (illustrative)

```
{
  "meta": {
    "snapshot": "EXAMPLE_TOKEN_RETURNED_BY_THE_API",
    "snapshot_expires_at": "2026-09-07T12:05:00Z",
    "as_of": "2026-09-07T12:00:00Z",
    "consistency": "snapshot",
    "page": 1,
    "page_size": 50,
    "has_more": true
  }
}
```

Snapshots last five minutes and hold at most 5,000 rows and 64 MiB of JSON, stored compressed within 4 MiB. At most three snapshots per account and sixteen globally can be active. Narrow filters after 413; honor Retry-After when capacity returns 429 or a snapshot read runs out of time with 503. A 410 requires a new snapshot on page 1. If a snapshot includes a change cursor, finish every snapshot page before advancing the cursor.

Change feeds contain retained observations, and target changes represent the latest material state per target. They are not an immutable event journal. Reconcile current inventory periodically and after disconnection; a cursor older than retained history returns 410 and requires resynchronization. Exports use a consistent read, return at most 500 targets, and report truncation in metadata.

MCP 0.2.3 exposes both change feeds and cursor polling. Its published tool schemas do not expose snapshot tokens; use the HTTP API when stable pages are required.

<a id="activity-signals"></a>

## Activity, payouts and derived signals

Read available views before requesting a ranking. These Pro routes use the same frozen calculations and explanations as the website. Keep nulls, bounds, source definitions and observation times intact. An observed increase does not identify an individual payment.

| GET route | Contract |
| --- | --- |
| /api/v1/pro/activity/capabilities | Available tabs, period/basis/precision combinations, sorts, directions and label filters. |
| /api/v1/pro/activity/rankings | One sortable page (limit 1–100) with meta.as_of, snapshot_id and next_cursor. Tabs: payouts, value, scope, rewards, updates, reports, response, status, all_changes. |
| /api/v1/pro/payouts/programs/{program_id} | Exact program facts, signals, labels, label_details and same-platform value_points. Handles may contain slashes. |
| /api/v1/pro/activity/events/{change_id} | Lazy before/after details; supply the originating ranking’s meta.snapshot_id as snapshot. |

Value uses lifetime payout per processed report and 90-day received volume, so omit period. It returns all matching map points (up to 5,000) separately from paginated rows. Platform percentiles are frozen before filters; label-specific shortlists may include programs without both map inputs. Use the advertised sort and direction and keep every filter unchanged with the cursor. A 410 requires a fresh query; a 422 means the requested view is unavailable or the selection must be narrowed. Private responses are no-store.

Example Value query

```
curl -sS "https://bbradar.io/api/v1/pro/activity/rankings?tab=value&labels=pays_near_top_reward&sort=realization&direction=desc&limit=25" -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

<a id="endpoints"></a>

## Endpoint reference

Each endpoint includes its purpose, parameters, cURL request, and an abbreviated response. Use the endpoint links to jump directly to a section.

<a id="endpoint-capabilities"></a>

### [GET`/api/v1/pro/capabilities`](https://bbradar.io/docs/api.md#endpoint-capabilities)

Negotiate the authenticated v1 contract, supported catalogs, route methods, filters, and hard result limits without querying catalog data.

Parameters and examples

Parameters

No query parameters

Bearer authentication is required

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/capabilities" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "api_version": "v1",
  "contract_version": "2026-09-06",
  "behavior": {
    "read_only": true,
    "private_cache_control": "no-store",
    "catalogs": ["platform", "self_hosted"],
    "scoring_version": 3,
    "submission_cost_policy_version": 1,
    "stable_snapshots": {
      "endpoints": ["programs", "target_search", "target_changes", "repository_changes"],
      "parameter": "snapshot", "start_value": "start", "ttl_seconds": 300,
      "max_rows": 5000, "max_bytes": 67108864, "max_decoded_bytes": 67108864,
      "max_stored_bytes": 4194304, "storage": "compressed", "expired_status": 410
    },
    "change_feed_contract": "latest retained state; reconcile inventory periodically; not an immutable event journal"
  },
  "endpoints": {
    "programs": { "method": "GET", "max_page_size": 100, "self_hosted": true },
    "program_detail": { "method": "GET", "self_hosted": true, "path_handles_may_contain_slashes": true },
    "program_targets": { "method": "GET", "max_page_size": 500, "self_hosted": true },
    "target_search": { "method": "GET", "max_page_size": 500, "self_hosted": true },
    "target_export": { "method": "POST", "max_targets": 500, "max_program_ids": 50, "max_request_body_bytes": 65536 },
    "target_changes": { "method": "GET", "max_page_size": 100, "self_hosted": false, "incremental_cursor": { "parameter": "after_id", "order": "ascending", "max_scan_rows": 2000, "returns_facets": false } },
    "repository_changes": { "method": "GET", "max_page_size": 100, "self_hosted": false, "includes_code_or_diff_content": false, "returns_facets": false, "max_association_rows_per_request": 5000, "incremental_cursor": { "parameter": "after_id", "order": "ascending", "skips_total_count": true }, "optional_summary_mode": { "parameter": "include_targets", "value": false, "returns_affected_programs": true } },
    "opportunities": { "method": "GET", "max_page_size": 100, "self_hosted": false }
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-programs"></a>

### [GET`/api/v1/pro/programs`](https://bbradar.io/docs/api.md#endpoint-programs)

List active and confirmed paused platform programs, plus active Self-Hosted programs, with server-side search, filters, and pagination.

Parameters and examples

Parameters

platforms (csv, optional)

Use platforms=Self-Hosted for only the Self-Hosted catalog

tags (csv, optional; scope, language, or target-type tags)

search (optional; name, handle, platform, policy host, or Self-Hosted target)

updated_since (ISO datetime, optional)

snapshot (optional; start on page 1, then reuse meta.snapshot with the same filters/account; expires after 5 minutes)

page (default: 1)

page_size (max: 100)

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/programs" \
  -G \
  --data-urlencode "page=1" \
  --data-urlencode "page_size=20" \
  --data-urlencode "search=example" \
  --data-urlencode "platforms=hackerone,bugcrowd,Self-Hosted" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "programs": [
    {
      "id": "HackenProof:example-handle",
      "handle": "example-handle",
      "name": "Example Program",
      "platform": "HackenProof",
      "link": "https://hackenproof.com/programs/example-handle",
      "profile_picture": "https://example.com/logo.png",
      "scope_tags": ["domain", "api"],
      "added_at": "2026-03-04T12:10:00Z",
      "date_launched": "2026-03-04",
      "last_updated": "2026-04-16T07:45:02Z",
      "targets_updated_at": "2026-04-16T07:45:02Z",
      "bounty_min": 100,
      "bounty_max": 5000,
      "report_count": 353,
      "submission_cost": {
        "amount": 5,
        "unit": "USD",
        "kind": "fee",
        "source": "hackenproof_catalog",
        "updated_at": "2026-04-16T07:45:02Z"
      },
      "up_votes": 48,
      "down_votes": 3,
      "total_votes": 51,
      "net_score": 45,
      "vote_ratio": 0.9412,
      "star_rating": 5,
      "review_signal": 3.9512437185814275,
      "weighted_sentiment": 19.756218592907137,
      "competitionRisk": "Medium",
      "competitionRiskReason": "Estimated from high public report count, less obvious asset type.",
      "target_counts": {
        "total": 42,
        "in_scope": 38,
        "out_of_scope": 4,
        "eligible_for_bounty": 32,
        "wildcard": 7
      },
      "target_activity": {
        "latest_change_at": "2026-04-16T07:45:02Z",
        "latest_added_at": "2026-04-15T09:20:31Z",
        "added_24h": 3,
        "added_7d": 9,
        "removed_7d": 1
      },
      "extra_data": {
        "report_count": 353,
        "report_count_source": "reports_received_last_90_days",
        "report_count_label": "reports received (last 90 days)"
      }
    }
  ],
  "meta": { "page": 1, "page_size": 20, "total": 120, "total_pages": 6 }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-program-detail"></a>

### [GET`/api/v1/pro/programs/{program_id}`](https://bbradar.io/docs/api.md#endpoint-program-detail)

Fetch one exact platform or Self-Hosted program without scanning list pages.

Parameters and examples

Parameters

program_id (required path param)

program_id format: platform:handle

Self-Hosted example: Self-Hosted:example-security

Handles containing "/" are supported

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/programs/Self-Hosted:example-security" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "id": "Self-Hosted:example-security",
  "handle": "example-security",
  "name": "Example Security",
  "platform": "Self-Hosted",
  "catalog": "self_hosted",
  "link": "https://example.com/security",
  "policy_url": "https://example.com/security",
  "policy_host": "example.com",
  "program_type": "paid",
  "reward_status": "paid",
  "reward_currency": "USD",
  "reward_types": ["cash"],
  "reporting_email": "security@example.com",
  "reporting_url": "https://example.com/report",
  "safe_harbor": "full",
  "verified_at": "2026-08-25T09:00:00Z",
  "scope_tags": ["api", "web"],
  "bounty_min": 100,
  "bounty_max": 5000,
  "report_count": null,
  "submission_cost": null,
  "date_launched": null,
  "data_capabilities": {
    "target_inventory": true,
    "target_changes": false,
    "opportunity_scoring": false,
    "public_report_count": false,
    "submission_cost": false,
    "repository_changes": false
  },
  "target_counts": {
    "total": 8,
    "in_scope": 7,
    "out_of_scope": 1,
    "eligible_for_bounty": 7,
    "wildcard": 2
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-opportunities"></a>

### [GET`/api/v1/pro/opportunities/{level}`](https://bbradar.io/docs/api.md#endpoint-opportunities)

List scored platform programs matching one opportunity tier. Self-Hosted rows are excluded because no opportunity score is fabricated.

Parameters and examples

Parameters

level (required path param: elite|hot|strong|potential)

platforms (csv, optional)

tags (csv, optional; scope, language, or target-type tags)

search (optional; name, handle, or platform)

updated_since (ISO datetime, optional)

page (default: 1)

page_size (max: 100)

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/opportunities/elite" \
  -G \
  --data-urlencode "page=1" \
  --data-urlencode "page_size=20" \
  --data-urlencode "platforms=hackerone,bugcrowd" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "programs": [
    {
      "id": "YesWeHack:example-handle",
      "handle": "example-handle",
      "name": "Example Program",
      "platform": "YesWeHack",
      "link": "https://yeswehack.com/programs/example-handle",
      "profile_picture": "https://example.com/logo.png",
      "scope_tags": ["domain", "api"],
      "added_at": "2026-04-10T12:10:00Z",
      "date_launched": "2026-04-10",
      "last_updated": "2026-04-16T07:45:02Z",
      "targets_updated_at": "2026-04-16T07:45:02Z",
      "bounty_min": 100,
      "bounty_max": 10000,
      "report_count": 1,
      "submission_cost": {
        "amount": 3,
        "unit": "credits",
        "kind": "fee",
        "source": "yeswehack_programs_api",
        "updated_at": "2026-04-16T07:45:02Z"
      },
      "up_votes": 48,
      "down_votes": 3,
      "total_votes": 51,
      "net_score": 45,
      "vote_ratio": 0.9412,
      "star_rating": 5,
      "review_signal": 3.9512437185814275,
      "weighted_sentiment": 19.756218592907137,
      "competitionRisk": "Low",
      "competitionRiskReason": "Estimated from very low public report count, less obvious asset type.",
      "target_counts": {
        "total": 42,
        "in_scope": 38,
        "out_of_scope": 4,
        "eligible_for_bounty": 32,
        "wildcard": 7
      },
      "target_activity": {
        "latest_change_at": "2026-04-16T07:45:02Z",
        "latest_added_at": "2026-04-15T09:20:31Z",
        "added_24h": 3,
        "added_7d": 9,
        "removed_7d": 1
      },
      "extra_data": {
        "report_count": 1,
        "report_count_source": "reports_received_last_90_days",
        "report_count_label": "reports received (last 90 days)"
      },
      "opportunity_tag": {
        "tier": "elite",
        "label": "Elite",
        "description": "Very fresh, lightly reported, and strong payout potential.",
        "reason": "Added 6 days ago • 1 public report • Up to $10,000 bounty",
        "opportunity_score": 97.5,
        "freshness": 100,
        "competition": 100,
        "reward": 90,
        "scope_bonus": 0,
        "signal_count": 3,
        "is_vdp": false
      }
    }
  ],
  "meta": {
    "level": "elite",
    "page": 1,
    "page_size": 20,
    "total": 8,
    "total_pages": 1
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-target-search"></a>

### [GET`/api/v1/pro/targets/search`](https://bbradar.io/docs/api.md#endpoint-target-search)

Reverse-search current platform and Self-Hosted target inventories without scanning program pages.

Parameters and examples

Parameters

q (optional; omit for paginated inventory; 2–512 characters when supplied)

match_mode (contains|exact|suffix|wildcard; default: contains)

snapshot (optional; start on page 1, then reuse meta.snapshot with the same filters/account; expires after 5 minutes)

platforms (csv, optional; supports Self-Hosted)

tags (csv, optional)

include_out_of_scope (bool; default: false)

include_ineligible (bool; default: false)

page (default: 1)

page_size (default: 50, max: 500)

cURL example

```
curl -sS -G "https://bbradar.io/api/v1/pro/targets/search" --data-urlencode "q=api.example.com" --data-urlencode "match_mode=suffix" --data-urlencode "platforms=Self-Hosted" -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "results": [
    {
      "program": {
        "id": "Self-Hosted:example-security",
        "handle": "example-security",
        "name": "Example Security",
        "platform": "Self-Hosted",
        "catalog": "self_hosted",
        "program_type": "paid",
        "policy_url": "https://example.com/security",
        "data_capabilities": {
          "target_inventory": true,
          "target_changes": false
        }
      },
      "target": {
        "target_type": "domain",
        "identifier": "api.example.com",
        "in_scope": true,
        "eligible_for_bounty": true,
        "is_active": true
      }
    }
  ],
  "meta": {
    "q": "api.example.com",
    "match_mode": "suffix",
    "page": 1,
    "page_size": 50,
    "total": 1,
    "total_pages": 1,
    "returned": 1,
    "has_more": false
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-targets"></a>

### [GET`/api/v1/pro/programs/{program_id}/targets`](https://bbradar.io/docs/api.md#endpoint-targets)

Fetch retained active target rows for one platform or Self-Hosted program. Paused parent status is included and bounty eligibility is disabled while paused; Target Intelligence appears only when supported.

Parameters and examples

Parameters

program_id (required path param)

program_id format: platform:handle

Handles can include "/" and are supported in this path

Example: BugCrowd:engagements/example-program

Self-Hosted example: Self-Hosted:example-security

eligibility (all|eligible|ineligible, optional)

target_type (optional)

search (optional; target identifier or display name)

minTargetScore (0-100, optional)

targetOpportunityLabel (Elite Target|Strong Target|Potential Target|Normal, optional)

competitionRisk (Low|Medium|High|Unknown, optional)

page (default: 1)

page_size (default: 250, max: 500)

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/programs/BugCrowd:engagements/example-program/targets" \
  -G \
  --data-urlencode "eligibility=eligible" \
  --data-urlencode "target_type=domain" \
  --data-urlencode "search=api" \
  --data-urlencode "minTargetScore=70" \
  --data-urlencode "targetOpportunityLabel=Strong Target" \
  --data-urlencode "competitionRisk=Low" \
  --data-urlencode "page=1" \
  --data-urlencode "page_size=250" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "targets": [
    {
      "target_type": "domain",
      "identifier": "*.example.com",
      "display_name": "*.example.com",
      "normalized_identifier": "example.com",
      "scope_tags": ["domain", "api"],
      "language_tags": ["javascript"],
      "in_scope": true,
      "eligible_for_bounty": true,
      "severity_score": 8.2,
      "severity_label": "High",
      "metadata": {},
      "source_url": "https://example.com/policy",
      "added_at": "2026-04-15T09:20:31Z",
      "source_added_at": "2026-04-14",
      "last_seen": "2026-04-16T07:45:02Z",
      "last_change_type": "added",
      "last_changed_at": "2026-04-15T09:20:31Z",
      "is_active": true,
      "wildcard": true,
      "targetOpportunityScore": 84,
      "targetOpportunityLabel": "Strong Target",
      "targetScoreBreakdown": {
        "freshness": { "score": 25, "label": "Last 7 days", "days": 3.1 },
        "targetType": { "score": 22, "label": "Wildcard", "key": "wildcard" },
        "reward": { "score": 22, "label": "High bounty", "maxBounty": 10000, "isNoReward": false },
        "reportActivity": { "score": 15, "label": "Very low public report count", "reportCount": 1, "fallback": null }
      },
      "competitionRisk": "Low",
      "competitionRiskReason": "Estimated from very low public report count, recent target change, less obvious asset type.",
      "whyThisTarget": "Fresh wildcard scope expansion, with eligible and in scope, high bounty potential, low competition risk."
    }
  ],
  "meta": {
    "page": 1,
    "page_size": 250,
    "total": 9809,
    "total_pages": 40,
    "returned": 250,
    "has_more": true
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-target-export"></a>

### [POST`/api/v1/pro/targets/export`](https://bbradar.io/docs/api.md#endpoint-target-export)

Export up to 500 current platform or Self-Hosted targets in one bounded request. Each JSON row preserves its parent program_id.

Parameters and examples

Parameters

program_ids (array, optional; max: 50)

platforms (array, optional; max: 15)

tags (array, optional; max: 25)

opportunity_levels (array: elite|hot|strong|potential; platform programs only)

include_out_of_scope (bool; default: false)

include_ineligible (bool; default: false)

format (json|csv; default: json)

limit (default/max: 500)

Request body size (max: 65,536 bytes)

When program_ids is non-empty it is the authoritative selection; catalog filters are ignored

Paused program scopes require explicit program_ids and include_ineligible=true; their bounty eligibility remains false

cURL example

```
curl -sS -X POST "https://bbradar.io/api/v1/pro/targets/export" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY" \
  -H "Content-Type: application/json" \
  --data '{"program_ids":["Self-Hosted:example-security"],"include_out_of_scope":false,"include_ineligible":false,"format":"json","limit":500}'
```

Example response

```
{
  "targets": [
    {
      "program_id": "Self-Hosted:example-security",
      "platform": "Self-Hosted",
      "program_handle": "example-security",
      "program_name": "Example Security",
      "catalog": "self_hosted",
      "target_type": "domain",
      "identifier": "api.example.com",
      "in_scope": true,
      "eligible_for_bounty": true,
      "wildcard": false,
      "is_active": true
    }
  ],
  "format": "json",
  "total": 1,
  "generated_at": "2026-08-25T09:00:00Z",
  "meta": {
    "returned": 1,
    "limit": 500,
    "has_more": false,
    "truncated": false,
    "programs_returned": 1
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-changes"></a>

### [GET`/api/v1/pro/targets/changes`](https://bbradar.io/docs/api.md#endpoint-changes)

Retrieve latest target additions, updates, and removals with target, parent-program, and submission-cost intelligence.

Parameters and examples

Parameters

change_type (added|readded|updated|removed)

snapshot (optional; start on page 1, then reuse meta.snapshot with the same filters/account; expires after 5 minutes)

include_removed (bool, optional)

include_ineligible (bool, optional)

include_out_of_scope (bool, optional)

search (min length: 2, optional)

platforms (csv, optional)

tags (csv, optional; scope, language, or target-type tags)

minTargetScore (0-100, optional)

targetOpportunityLabel (Elite Target|Strong Target|Potential Target|Normal, optional)

competitionRisk (Low|Medium|High|Unknown, optional)

page (default: 1)

page_size (max: 100)

after_id (optional; incremental polling cursor, page must remain 1)

Cursor mode is oldest-first, scans at most 2,000 candidate rows, omits totals and facets, and returns next_after_id

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/targets/changes" \
  -G \
  --data-urlencode "change_type=added" \
  --data-urlencode "search=example" \
  --data-urlencode "minTargetScore=70" \
  --data-urlencode "targetOpportunityLabel=Strong Target" \
  --data-urlencode "competitionRisk=Low" \
  --data-urlencode "page=1" \
  --data-urlencode "page_size=50" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "results": [
    {
      "id": 48102,
      "change_type": "added",
      "changed_at": "2026-04-15T09:20:31Z",
      "program": {
        "id": "Sherlock:example-program",
        "handle": "example-program",
        "name": "Example Program",
        "platform": "Sherlock",
        "link": "https://audits.sherlock.xyz/bug-bounties/example-program",
        "scope_tags": ["domain", "api"],
        "bounty_min": 100,
        "bounty_max": 5000,
        "submission_cost": {
          "amount": 0,
          "maximum_amount": 250,
          "unit": "USDC",
          "kind": "deposit",
          "source": "sherlock_bug_bounties_api",
          "updated_at": "2026-04-16T07:45:02Z"
        },
        "profile_picture": "https://example.com/logo.png",
        "date_launched": "2026-03-04",
        "targets_updated_at": "2026-04-16T07:45:02Z",
        "competitionRisk": "Low",
        "competitionRiskReason": "Estimated from low public report count, less obvious asset type."
      },
      "target": {
        "identifier": "*.api.example.com",
        "normalized_identifier": "api.example.com",
        "display_name": "*.api.example.com",
        "type": "domain",
        "scope_tags": ["domain", "api"],
        "language_tags": ["javascript"],
        "in_scope": true,
        "eligible_for_bounty": true,
        "wildcard": true,
        "source_url": "https://example.com/policy",
        "added_at": "2026-04-15T09:20:31Z",
        "source_added_at": "2026-04-14",
        "last_seen": "2026-04-16T07:45:02Z",
        "is_active": true,
        "severity_score": 8.2,
        "severity_label": "High",
        "targetOpportunityScore": 87,
        "targetOpportunityLabel": "Elite Target",
        "targetScoreBreakdown": {
          "freshness": { "score": 35, "label": "Last 24 hours", "days": 0.4 },
          "targetType": { "score": 22, "label": "Wildcard", "key": "wildcard" },
          "reward": { "score": 18, "label": "Strong bounty", "maxBounty": 5000, "isNoReward": false },
          "reportActivity": { "score": 12, "label": "Low public report count", "reportCount": 4, "fallback": null }
        },
        "competitionRisk": "Low",
        "competitionRiskReason": "Estimated from low public report count, recent target change, less obvious asset type.",
        "whyThisTarget": "Fresh wildcard scope expansion, with eligible and in scope, strong reward potential, low competition risk."
      },
      "metadata": {},
      "diff": {}
    }
  ],
  "meta": {
    "page": 1,
    "page_size": 50,
    "total": 218,
    "total_pages": 5,
    "change_type": "added",
    "included_change_types": ["added"],
    "include_removed": false,
    "include_ineligible": false,
    "include_out_of_scope": false,
    "last_sync": "2026-04-16T07:45:02Z",
    "previous_sync": "2026-04-16T07:44:11Z",
    "applied_since": null
  },
  "facets": {
    "platforms": [
      { "value": "hackerone", "label": "HackerOne", "count": 120 }
    ],
    "tags": [
      { "value": "domain", "label": "domain", "count": 163 }
    ]
  }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="endpoint-repository-changes"></a>

### [GET`/api/v1/pro/repositories/changes`](https://bbradar.io/docs/api.md#endpoint-repository-changes)

Retrieve bounded repository/ref transitions and their affected platform programs and targets. The response contains no patches, source code, commit messages, changed paths, filenames, or diff statistics.

Parameters and examples

Parameters

search (2-128 characters, optional; repository, ref, platform, program, or target)

platforms (csv, optional; max: 15)

tags (csv, optional; scope, language, or target-type tags; max: 25)

free_submission_only (bool; default: false)

snapshot (optional; start on page 1, then reuse meta.snapshot with the same filters/account; expires after 5 minutes)

include_removed (bool; default: false)

include_ineligible (bool; default: false)

include_out_of_scope (bool; default: false)

page (default: 1)

page_size (default: 50, max: 100)

after_id (optional; incremental polling cursor, page must remain 1)

include_targets (bool; default: true; false omits nested targets but preserves affected programs)

Cursor mode is oldest-first, skips the total-count query, and returns next_after_id

minTargetScore, targetOpportunityLabel, and competitionRisk require page mode and cannot be combined with after_id

Global facet aggregation is omitted so automation requests do not scan the full repository-link catalog

Requests exceeding 5,000 nested program/target associations return 413; narrow filters or page_size

Platform catalog only; Self-Hosted repository-change coverage is unavailable

cURL example

```
curl -sS -X GET "https://bbradar.io/api/v1/pro/repositories/changes" \
  -G \
  --data-urlencode "search=contracts" \
  --data-urlencode "platforms=Immunefi" \
  --data-urlencode "tags=solidity" \
  --data-urlencode "page=1" \
  --data-urlencode "page_size=50" \
  -H "Authorization: Bearer YOUR_PRO_API_KEY"
```

Example response

```
{
  "results": [
    {
      "id": 17042,
      "event_type": "push",
      "source": "poll",
      "ref_name": "main",
      "before_sha": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
      "after_sha": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
      "observed_at": "2026-08-27T05:30:00Z",
      "repository": {
        "provider": "github",
        "provider_host": "github.com",
        "full_name": "example/contracts",
        "url": "https://github.com/example/contracts"
      },
      "changes_url": "https://github.com/example/contracts/compare/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
      "link_type": "compare",
      "programs": [
        { "id": "Immunefi:example", "platform": "Immunefi", "handle": "example", "name": "Example Protocol" }
      ],
      "targets": [
        {
          "id": 901,
          "type": "source code",
          "identifier": "https://github.com/example/contracts",
          "path_kind": "repository",
          "path_prefix": null,
          "in_scope": true,
          "eligible_for_bounty": true,
          "is_active": true,
          "scope_tags": ["smart contract", "source code"],
          "language_tags": ["solidity"]
        }
      ]
    }
  ],
  "meta": { "page": 1, "page_size": 50, "total": 1, "total_pages": 1 }
}
```

See [Errors and retries](https://bbradar.io/docs/api.md#errors) for invalid requests, authentication, expiry, size limits, and temporary failures.

<a id="limits"></a>

## Rate and concurrency limits

ScopeLimitNotes

Programs and opportunities`80 requests/min`

/programs and /opportunities/{level} share this endpoint bucket.

Targets, search, and export`40 requests/min`

/programs/{program_id}/targets, /targets/search, and /targets/export share this endpoint bucket.

Target and repository changes`30 requests/min`

/targets/changes and /repositories/changes share this endpoint bucket.

Global key bucket`120 requests/min, burst 300`

Shared by all Pro API v1 requests for the same API key.

Per key + IP bucket`60 requests/min`

Applied to one API key from one source IP.

Concurrent requests`8 per key, 3 change feeds`

Target and repository changes share a smaller concurrent cap because they are the heaviest endpoints.

Distinct IP guard`5 IPs/hour`

Exceeding this locks the key for 10 minutes. Three locks in 24 hours locks it for 24 hours.

Responses include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`. A `429` response also includes `Retry-After`.

<a id="errors"></a>

## Errors and retries

Retry only transient failures, reduce concurrency, and use jitter to avoid synchronized traffic.

`400`

Invalid parameter or request shape.

Correct the request; do not retry it unchanged.

`401`

Missing, malformed, revoked, or incorrect API key.

Check the Bearer header and the current key.

`402`

The account no longer has active Pro access.

Restore Pro access before retrying.

`404`

The requested program or resource was not found.

Verify the composite program ID and URL encoding.

`410`

A snapshot expired or the change cursor predates retained history.

Start a fresh snapshot on page 1, or reconcile current inventory before restarting the change cursor.

`413`

A request body, snapshot, or repository association result exceeds its size limit.

Narrow the selection or reduce the page size; do not retry the same oversized request.

`423`

The key is temporarily locked by abuse protection.

Stop traffic and wait until the lock expires.

`429`

A rate or concurrency limit was exceeded.

Honor Retry-After and retry with exponential jitter.

`503`

A required service is temporarily unavailable.

Honor Retry-After when present and retry with bounded backoff.
