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
Free1,000030
Developer10,00010,000120
Pro100,000100,000300
Growth500,000100,000600
Lead Feed1,000,000250,0001,200
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.

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: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1719367200
RateLimit: "default";r=117;t=42

429 Envelope

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 17
X-RateLimit-Limit: 120
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