Claim your free listing
Skip to content

aba-rank Agent API - Quickstart Guide

This guide complements the interactive reference at /docs/api. Read this first, then jump to the reference for endpoint-by-endpoint details and try-it-out.

Authentication

Anonymous reads work out of the box (rate-limited per IP). For higher limits and write access, create an API key at /account/api-keys and pass it as a Bearer token:

curl https://www.abarank.com/api/v1/vendors \
  -H "Authorization: Bearer abr_live_XXXXXXXX..."

Keys come in two flavors: abr_live_* (production) and abr_test_* (preview / dev). Scope is locked at key creation -read by default; check write:leads to also callPOST /api/v1/leads.

Rate limits

Every response includes both X-RateLimit-* and IETF RateLimit-* headers:

X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 60
RateLimit-Limit: 300
RateLimit-Remaining: 287
RateLimit-Reset: 60

Reset values are delta seconds in both header families - the number of seconds until the current window resets, not an epoch timestamp. (We emit the same delta value on X-RateLimit-Reset as the IETF RateLimit-Reset for consistency.)

When exhausted you get an HTTP 429 with Retry-After header and matching retry_after body field.

TierReadsWrites
Anonymous (no key)60 req / minute / IP, 1000 / hour / IPNot permitted
Keyed (any tier)300 req / minute / key + 10,000 / hour / key30 req / minute / key + 500 / hour / key (if scope granted)

Retry guidance: on 429, sleep for the duration in Retry-After seconds (or RateLimit-Reset) before retrying. Exponential backoff is unnecessary - our window is fixed.

Error codes

Every non-2xx response uses the same envelope: { error: { code, message, details?, retry_after? }, meta: { as_of } }.

CodeHTTPMeaning
invalid_api_key401Missing, malformed, or revoked Bearer token
invalid_scope403Key lacks the scope required by the endpoint
rate_limited429Per-IP or per-key rate limit exceeded
attestation_required400Required attestation field (e.g. agent_disclosure) missing or false
invalid_pagination400per_page out of [1..100] or cursor malformed
not_found404Resource (vendor, clinic, article, category) does not exist or is not public
validation_failed400Request body failed schema validation; details holds field-level issues
conflict409Request collides with current resource state (e.g. buyer-open-cap exceeded). Distinct from validation_failed: do not retry without changing context (e.g. different buyer email).
internal_error500Unhandled server error; please retry with backoff and report if persistent

Example payloads

invalid_api_key
{ "error": { "code": "invalid_api_key", "message": "Missing or invalid API key" } }
invalid_scope
{ "error": { "code": "invalid_scope", "message": "This endpoint requires scope: write:leads" } }
rate_limited
{ "error": { "code": "rate_limited", "message": "Too many requests", "retry_after": 30 } }
attestation_required
{ "error": { "code": "attestation_required", "message": "Required attestation field missing or invalid", "details": { "issues": [{ "path": "agent_disclosure", "message": "Invalid literal value" }] } } }
invalid_pagination
{ "error": { "code": "invalid_pagination", "message": "per_page must be an integer between 1 and 100" } }
not_found
{ "error": { "code": "not_found", "message": "Vendor 'foo' not found" } }
validation_failed
{ "error": { "code": "validation_failed", "message": "Lead submission validation failed", "details": { "issues": [...] } } }
conflict
{ "error": { "code": "conflict", "message": "Buyer has too many open leads", "details": { "code": "lead.buyer_open_cap_exceeded" } } }
internal_error
{ "error": { "code": "internal_error", "message": "Something went wrong" } }

MCP quickstart (Claude Desktop / Claude Code)

Paste this into your MCP config to expose aba-rank tools (read tools work without auth; submit_lead appears only when an API key is provided):

{
  "mcpServers": {
    "aba-rank": {
      "url": "https://www.abarank.com/api/mcp",
      "transport": "http",
      "headers": {
        "Authorization": "Bearer abr_live_XXXXXXXX..."
      }
    }
  }
}

Available tools: search_vendors, get_vendor, search_clinics, get_clinic, list_categories, list_subcategories, get_articles, search_all, get_methodology, submit_lead (write:leads scope).

Ranking methodology

Every vendor + clinic response includes rank_score, a normalized 0–1 value (3 decimal places) — multiply by 100 for the 100-point Index published at /how-we-rank — plus rank_position (1-indexed within category) and the methodology version (currently 3.0). The weights are the exact coefficients in the engine, served as JSON at /api/v1/methodology:

The weights sum to 1.0 and every term is operational: as of methodology 3.0 there is no purchasable input to rank_score and no multiplier applied after the sum.

Sponsor cap: Sponsored placements are capped (no more than 25 of 100 results in any ranked list), rendered in labeled slots above the ranked list, and never change rank_score. As of methodology v3.0 no paid product of any kind contributes Index points: subscription tier is not an input to the ranking formula.

Versioning + changelog policy

URL prefix /api/v1/ is the contract surface. What v1 guarantees:

Copy-paste examples

Search vendors (curl)

curl "https://www.abarank.com/api/v1/vendors?type=software&per_page=5" \
  -H "Authorization: Bearer abr_live_XXXXXXXX..."

Search vendors (JavaScript fetch)

const res = await fetch('https://www.abarank.com/api/v1/vendors?type=software&per_page=5', {
  headers: { Authorization: 'Bearer abr_live_XXXXXXXX...' },
});
const { data, meta } = await res.json();
console.log(data, meta.cursor);

Get a vendor (curl)

curl https://www.abarank.com/api/v1/vendors/centralreach

Get a vendor (fetch)

const { data } = await (await fetch('https://www.abarank.com/api/v1/vendors/centralreach')).json();
console.log(data.aggregate_rating); // present only when published reviews >= 3

Geo-search clinics (curl)

curl "https://www.abarank.com/api/v1/clinics?lat=34.05&lng=-118.24&radius_km=25"

Unified search (curl)

curl "https://www.abarank.com/api/v1/search?q=billing"

Submit a lead (curl)

curl https://www.abarank.com/api/v1/leads \
  -X POST \
  -H "Authorization: Bearer abr_live_XXXXXXXX..." \
  -H "Content-Type: application/json" \
  -d '{
    "vendor_slug": "centralreach",
    "acting_for_user": {
      "name": "Sarah Chen",
      "contact_email": "sarah@example.com",
      "stated_need": "ABA practice management for a 50-clinician clinic"
    },
    "agent_disclosure": true,
    "agent_id": "claude-opus-4-7"
  }'

Submit a lead (fetch)

await fetch('https://www.abarank.com/api/v1/leads', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer abr_live_XXXXXXXX...',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    vendor_slug: 'centralreach',
    acting_for_user: {
      name: 'Sarah Chen',
      contact_email: 'sarah@example.com',
      stated_need: 'ABA practice management for a 50-clinician clinic',
    },
    agent_disclosure: true,
  }),
});

For the full interactive reference (every endpoint, every field, try-it-out), head to /docs/api.