Florida Business API

Rate Limits

Per-tier monthly quotas, per-minute rate limits, response headers, and the 429 envelope.

Florida Business API enforces two limits on every /api/v1/* request:

  1. Monthly quota — total requests allowed per calendar month, by plan.
  2. Per-minute rate limit (RPM) — a sliding-window burst limit, also by plan.

Whichever you hit first returns 429 rate_limited with a Retry-After header. Both buckets are backed by Upstash Redis with a 1-second timeout that fails open (we'd rather under-bill than 5xx your job).

Florida Business API is an independent data platform and is not affiliated with Sunbiz.org, the Florida Department of State, or the Florida Division of Corporations.

Tiers

PlanMonthly Quota (REST)Monthly MCP CallsRPM (burst)RESTMCPWebhooks
MCP Starter ($5/mo)1,00030
Free (trial)500 at signup, full access 7 days then capped at min(remaining, 100)030
Developer5,0005,00060
Pro25,00025,000150
Growth100,000100,000300
Lead Feed250,000250,000600
Enterprise"Unlimited" (2B cap)"Unlimited" (2B)10,000

The MCP Starter tier intentionally excludes REST — REST requests on a Starter key return 403 rest_disabled (see Errors). Every other tier enables both surfaces. "Unlimited" Enterprise is modeled as a 2,000,000,000-row cap so the Postgres INT column does not overflow; in practice the limit is the contract.

The Free tier is a 7-day trial: each new client is granted 500 credits at signup. For the first 7 days you have full access to whatever balance remains. On the first API call after day 7, your balance is automatically capped at min(remaining_balance, 100) — a one-shot adjustment recorded in the credit ledger as free_trial_expired_cap. After that, when the remaining credits run out the API returns 402 Payment Required with an upgrade hint pointing at /pricing. Upgrading to any paid tier removes the cap and swaps the gate to the recurring monthly grant.

Response Headers

Every /api/v1/* response (including 429) includes both the legacy de-facto headers and the IETF draft RateLimit structured field — pick whichever your HTTP client supports:

HeaderMeaning
X-RateLimit-LimitYour plan's RPM cap.
X-RateLimit-RemainingRequests remaining in the current 60-second window.
X-RateLimit-ResetUnix seconds at which the window resets.
RateLimitRFC 9651 structured field: "default";r=<remaining>;t=<seconds_until_reset>.
Retry-AfterOnly on 429. Seconds until you may retry.

Example success headers:

HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 57
X-RateLimit-Reset: 1719367200
RateLimit: "default";r=57;t=42

429 Envelope

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 17
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 17
RateLimit: "default";r=0;t=17
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after 17 seconds.",
    "request_id": "req_1234567890abcdef12345"
  }
}

Handling 429s

The simplest correct strategy: sleep Retry-After seconds, then retry once.

while :; do
  RESP=$(curl -s -w "\n%{http_code}" \
    -H "Authorization: Bearer fbapi_live_..." \
    "https://api.floridabusinessapi.com/v1/entities/search?name=ACME")
  CODE=$(printf '%s\n' "$RESP" | tail -n1)
  BODY=$(printf '%s\n' "$RESP" | sed '$d')
  [ "$CODE" = "200" ] && { echo "$BODY"; break; }
  [ "$CODE" = "429" ] && { sleep "${Retry_After:-30}"; continue; }
  echo "fatal: $CODE$BODY" >&2; exit 1
done

For long-running batch jobs, use exponential backoff capped at the X-RateLimit-Reset value — you will never wait longer than the window itself.

Monthly Quota vs. RPM

  • Hitting RPM returns 429 and resets within ~60 seconds. Slow down and you can finish your job today.
  • Hitting monthly quota also returns 429, but Retry-After will be the seconds until your next billing cycle. Upgrade or wait — there is no in-cycle escape hatch.

Check current consumption from the Account Usage endpoint.

On this page