Signals: hot (new or changed in the last 30 days), new_in_days, a change log (new_business, site_launched, platform_changed, pixel_added, pixel_removed, closed).
No reviews, star ratings or photos. Ever. See methodology for sources, freshness and accuracy.
Authentication
Create a key at /app/api-keys (creating your first key also grants the +750 connect bonus). Send it as a bearer token.
Keys can carry their own monthly spend cap; the account cap always applies too.
headerhttp
Authorization: Bearer ob_live_c9b298ba67d3…
Browser sessions in the app use the same endpoints with a session token. Free aggregate endpoints need no credential at all.
Free vs paid
Endpoint
Cost
Returns
GET /v1/coverage
Free, no key
Collection counters, covered cities
GET /v1/stats, POST /v1/stats/polygon
Free, no key
Counts and breakdowns. Never names, IDs or coordinates. Counts under 5 come back as "<5".
GET /v1/categories
Free, no key
The category vocabulary with national counts
GET /v1/businesses
Free
Names + signals + a cost estimate. No contacts.
GET /v1/businesses/{id}
3 credits, 10 if hot
The full record including phone, emails, website
GET /v1/changes
Free list
Change events with business summaries; opening a record bills as above
POST /v1/exports → /confirm
Per record, charged on confirm
CSV of full records
POST /v1/report-card
Free
Website score for one domain
Credits
1 credit = $0.01. Prepaid, no subscription.
Standard record: 3 credits ($0.03).
Hot record (new or changed in the last 30 days): 10 credits ($0.10).
Once per unique record per calendar month. Open the same business twice in October, pay once. Exports skip records you already opened this month.
Free credits: 250 on signup with a business email (one grant per domain), +750 when you create an API key / connect MCP or install TagFrog on a client site. Free credits expire after 30 days.
Spend caps: per account (PUT /v1/billing/spend-cap) and per key. Over the cap, paid calls return 402 spend_cap; nothing else breaks.
Every paid response includes credits_used and balance_remaining so an agent can reason about budget without an extra call.
Three calls: a free aggregate, a free search, one paid reveal.
quick startbash
# 1. Free: how many dentists in Portland, and how many fail Core Web Vitals?
curl "https://opsblu.com/v1/stats?state=oregon&city=portland&category=dentists"
# 2. Free: list the failing ones (names + signals, no contacts) with a cost estimate
curl -H "Authorization: Bearer ob_live_YOUR_KEY" \
"https://opsblu.com/v1/businesses?state=oregon&city=portland&category=dentists&cwv_fail=true&limit=25"
# 3. Paid: open one record (3 credits, 10 if hot)
curl -H "Authorization: Bearer ob_live_YOUR_KEY" "https://opsblu.com/v1/businesses/ob_por_den_0007"
Prefer an agent? Connect via MCP and ask: "How many dentists in Portland fail Core Web Vitals? Show me 10, don't open any records yet."
Rate limits
Anonymous and free endpoints are limited per IP (about 120 requests a minute). Keys get higher limits. Over the limit you get a
429 with a friendly body, not an error wall. Back off for retry_after seconds and continue.
429 slow_downjson
{ "error": "slow_down", "message": "You're moving fast. Give it a few seconds and try again.", "retry_after": 12 }
Abuse controls (coverage-ratio throttling, progressive latency, per-key caps, canary records) run server-side. Scrape-like access patterns slow down before they stop.
Errors
All errors are JSON: { "error": "<code>", "message": "<human text>" }.
HTTP
error
Meaning
400
bad_request
Missing or invalid parameter; the message says which.
401
auth_required
Paid endpoint with no credential.
401
auth_invalid
Key revoked or token expired.
402
insufficient_credits
Balance too low. Top up at /app/billing.
402
spend_cap
Monthly spend cap reached (account or key).
403
business_email_required
Free-credit grants need a business email domain. You can still buy credits.
404
not_found
Unknown id, slug or token.
409
already_granted / bad_state
Bonus already claimed; export already confirmed.
410
expired
Sample link past its 60-day window.
429
slow_down
Rate limited; honor retry_after.
Recipes
Each recipe is a real task written twice: as REST calls and as an agent prompt.
On our own site we track these product events (via TagFrog → GA4): search_submitted, draw_completed, category_chip_clicked, persona_selected,
email_gate_shown, email_captured, signup_completed, free_credits_granted, mcp_connected, report_card_run, sample_page_viewed, sample_cta_clicked,
topup_started, topup_completed, record_revealed, export_confirmed, territory_saved, alert_configured, removal_requested. We do not track your
API calls beyond what billing requires. Details in privacy.