Docs
Reference
Errors & Status Codes

Errors & Status Codes

Every error response returns a JSON object with an error field describing what went wrong.

{
  "error": "Description of the problem"
}

HTTP status codes

CodeMeaningWhen
400Bad RequestMissing or invalid parameters
401UnauthorizedMissing, invalid, inactive, or expired API key
402Payment RequiredOut of usage, or an account outside the Frontrun network with no private-source slot left (PRIVATE_SOURCE_PACK)
403ForbiddenTracking limit reached (tracking_cap), a discovery lane not on your plan (lanes_not_enabled), or another tier limit
404Not FoundAccount not tracked, resource doesn't exist
409ConflictResource already exists (e.g., already tracking account)
429Too Many RequestsRate limit or daily usage cap exceeded
500Internal ErrorServer-side issue - retry with backoff
503Service UnavailableUpstream (X/Twitter) temporarily unreachable - retry

Error responses by type

401 - Authentication

{ "error": "Missing X-API-Key header" }
{ "error": "Invalid or inactive API key" }
{ "error": "API key expired" }

Verify your API key is correct, active, and unexpired. Keys can be managed in the Developer Portal (opens in a new tab).

402 - Out of usage

{
  "error": "out_of_usage",
  "error_code": "out_of_usage",
  "message": "You're out of usage for this month. Upgrade to Max for 4x the usage of Pro, or top up.",
  "usage_pct": 100,
  "usage_resets_at": "2026-11-01T00:00:00Z",
  "plan": "pro",
  "upgrade": "https://frontrun.vc/pricing",
  "top_up": "https://frontrun.vc/api/billing",
  "top_up_now": {
    "endpoint": "POST https://frontrun.vc/v1/billing/topup",
    "body": { "pack": "pack_1000", "auto_refill": false },
    "mcp_tool": "frontrun_topup",
    "packs": [
      { "id": "pack_1000", "label": "Small top-up", "price_usd": 25 },
      { "id": "pack_5000", "label": "Medium top-up", "price_usd": 120 },
      { "id": "pack_10000", "label": "Large top-up", "price_usd": 220 }
    ],
    "note": "Charges the card on file and credits this key at once, so the next call succeeds. Pass auto_refill: true to buy the same pack automatically whenever usage runs low. A key with no card on file gets a checkout link instead."
  }
}

This period's usage is used up. An agent can continue without a browser: top_up_now names the endpoint and the MCP tool that buy a pack with the card on file and credit the key in the same call (Billing & top-ups). Otherwise upgrade, top up in the app, or wait for usage_resets_at.

429 - Rate limited

Two types of 429 responses:

Per-minute rate limit:

{
  "error": "API rate limit exceeded. Please slow down.",
  "retry_after_seconds": 60
}

Daily usage cap reached:

{
  "error": "Daily usage cap reached",
  "error_code": "daily_cap",
  "tier": "pro",
  "resets_at": "2026-03-12T00:00:00.000Z"
}

The daily usage cap prevents runaway agent costs. It resets at midnight UTC.

400 - Invalid parameters

{ "error": "username is required" }
{ "error": "Invalid \"since\" parameter. Use \"24h\", \"7d\", or \"YYYY-MM-DD\"." }
{
  "error": "At least one filter required: sector, keyword, or entity_type",
  "example": "/v1/search?sector=AI/ML&entity_type=startup"
}

Errors from the agent-oriented parameters carry an error_code so they can be branched on without string matching. See Budgets & Cursors.

max_credits_exceeded - the call could cost more than the ceiling you set. It fails closed: no work ran and nothing was charged. Retry with a smaller limit, fewer include sections, or a higher ceiling.

{
  "error": "This call could cost more than your max_credits ceiling. Nothing was charged and no work was done.",
  "error_code": "max_credits_exceeded",
  "max_credits": 200,
  "hint": "Lower limit, drop classify=true, or raise max_credits."
}

invalid_cursor - the cursor was modified, or is being replayed against a different endpoint, API key, or filter set. Cursors are opaque and scoped; mint a fresh one with since.

{
  "error": "This cursor was issued for a different endpoint, API key, or filter set. Cursors are scoped; start a fresh run with since when you change filters.",
  "error_code": "invalid_cursor"
}

invalid_include - an unknown section name was passed to GET /v1/company/:handle?include=. Allowed: resources, founders, funding.

batch_too_large - more items than the endpoint's batch ceiling. The response carries max_batch_size and received.

{
  "error": "Max 50 usernames per request. Split the list and call again.",
  "error_code": "batch_too_large",
  "max_batch_size": 50,
  "received": 150
}

403 - Tracking limit

tracking_cap - POST /v1/track with a key created from a Frontrun account, when you are at your plan's tracking limit (Free 0, Pro 250, Max 750, custom and Enterprise plans their own cap). Accounts you already track keep working; you just cannot add more.

{
  "error": "Tracking limit reached (250 accounts).",
  "error_code": "tracking_cap",
  "account_limit": 250,
  "tracking": 250,
  "swaps_this_week": 27,
  "free_swaps_per_week": 25,
  "held_slots": 2,
  "overage_hint": "Pro can go past 250 at $0.25 per account per month: turn on automatic expansion in Settings > Billing.",
  "hold_note": "You get 25 free swaps a week. Past that, an account you stop tracking keeps its slot for 7 days.",
  "next_slot_free_at": "2026-10-02T15:20:00.000Z"
}

hold_note and next_slot_free_at appear only when slots are held. You get 25 free swaps per rolling 7 days: untrack an account and the slot frees immediately. Past 25, an untracked account keeps its slot for 7 days. On Pro, turn on automatic expansion in Settings > Billing to go past 250. In a batch POST /v1/track, the handle's status is tracking_cap instead of a 403. See Tracking limits.

402 - Private source needs a pack

PRIVATE_SOURCE_PACK - POST /v1/track for an X account that is not in the Frontrun network (the catalog every customer picks from). Accounts outside the network are private sources: $20/mo per 100, bought in Settings > Billing. Accounts in the network never return this.

{
  "error": "@somehandle is outside the Frontrun network. Private sources are $20/mo per 100.",
  "code": "PRIVATE_SOURCE_PACK",
  "handle": "somehandle",
  "used": 100,
  "allowance": 100,
  "packs": 1,
  "pack": { "size": 100, "cents": 2000 },
  "eligible": true,
  "hint": "Buy private sources in Settings > Billing (100 for $20/mo), then retry."
}

In a batch POST /v1/track, the handle's status is private_source_pack instead of a 402.

403 - Discovery lane not on your plan

lanes_not_enabled - GET /v1/people, GET /v1/accelerators, or POST /v1/webhooks with a people / accelerators event, from a key whose plan does not include the discovery lanes. accelerator_lane_not_enabled - the plan has the stealth lane but not the accelerator lane. lanes_need_account_key - a standalone key (no Frontrun account) asked for a lane; use a key created from your account.

{
  "error": "The People (stealth founders) and Accelerator lanes are not on your plan yet.",
  "error_code": "lanes_not_enabled"
}

Check lanes.people and lanes.accelerators in GET /v1/status before calling. See Pricing for which plans include the lanes.

403 - Tier limit

Returned when an action would exceed your subscription tier's quota, for example the database-level tracked-account quota.

{
  "error": "You have reached your limit of 25 tracked accounts. Please upgrade your plan to track more.",
  "code": "TRACKED_ACCOUNT_LIMIT",
  "tier": "free"
}

Upgrade your subscription or untrack existing accounts (DELETE /v1/track/:username) before adding new ones.

404 - Not found

{ "error": "Not tracking @example. Add with POST /v1/track" }

The account must be tracked before you can query follows, convergence, or activity.

409 - Already exists

{
  "error": "Already tracking this account",
  "ready": true
}

503 - Upstream unavailable

Returned by the handle-lookup endpoints (/v1/preview/:h, /v1/company/:h, /v1/company/:h/signals, /v1/company/:h/resources, /v1/company/:h/funding, /v1/company/:h/founders, /v1/track) when the upstream X/Twitter data provider is slow or temporarily unreachable.

{
  "error": "Twitter upstream temporarily unavailable. Please retry.",
  "retry_after_seconds": 30
}

The response includes a Retry-After: 30 HTTP header. Back off for the indicated interval and retry - these are transient and usually clear within a minute.

Retry guidance

ErrorRetry?Strategy
400NoFix the request parameters
401NoCheck your API key
402NoUpgrade or top up
403NoUpgrade plan, turn on automatic expansion (Pro), or untrack accounts. For tracking_cap with held slots, wait until next_slot_free_at
404NoTrack the account first via POST /v1/track
409NoResource already exists - this is a no-op
429 (rate limit)YesWait retry_after_seconds, then retry
429 (daily usage cap)YesWait until resets_at timestamp
500YesExponential backoff: 1s, 2s, 4s, max 3 retries
503YesWait retry_after_seconds (from body or Retry-After header), then retry