Integrators

The apifare integrator contract

Everything a host product needs to ship apifare as a provider: the wire contract, conformance levels for the payment moment, fixtures for every error class, measured latency, limits, and the retention policy — written so your reviewer can hold us to it. Versioned; changes are announced, never silent.

1 · The integration unit

An optional provider inside your abstraction — a router slot, a provider module, an extension. Never a hard dependency, never a replacement for BYOK, and explicit-only selection: apifare must be chosen by your user or operator (config, settings, or per-call), never auto-selected merely because credentials exist. Your selection logic stays authoritative; we never substitute providers on our side.

2 · Wire contract

Plain HTTPS, one bearer header. POST /v1/call/{slug} with a JSON body; discovery via GET /v1/search?q=… (results carry the route and the exact price). Search (dataforseo): {"q", "count"?≤100, "country"?, "language"?}result.results[] = {title, url, description, position}. Fetch (scrape): {"url"}result.{url, status, markdown}. Machine indexes: /openapi.json · /agents.json · /llms.txt. An MCP server (apifare-mcp on npm) exists for MCP-native hosts.

Env names: APIPAY_TOKEN (legacy) and APIFARE_TOKEN are BOTH supported indefinitely — third-party integrations depend on each. What we actually read is the Authorization bearer header, so in your own code the variable name is yours to choose; the name only matters where you configure our stdio server apifare-mcp, which reads APIPAY_TOKEN in the current release (0.4.1). Deprecation policy: nothing an integrator depends on is removed without 12 months' notice on this page and support for both old and new forms throughout; this page is the canonical announcement channel.

3 · Pricing model

Prepaid credits, 1 credit = $0.01, flat per call: search 0.3cr · fetch 0.3cr · weather 0.1cr; marketplace tools reserve 5cr and settle to true metered cost (ceiling 20cr; the response carries x-apipay-reserved and x-apipay-credits-charged). The listed price is the billed price — our CI fails if site copy and billing drift. Failed provider calls auto-refund (fixture 5). New accounts: 500 trial credits, 14-day expiry; purchased credits never expire. Zero results from a search is a delivered, billed answer; an undelivered result is refunded.

4 · The payment moment — two conformant modes

When a call returns 402, a conformant integration does one of:

RELAY — surface the body's human_readable and topup_url to the human, verbatim, and retry the same call after payment. This is the native flow: in our live rehearsal the human paid and the same call resumed 44 seconds later.

GRACEFUL — fall back to another provider with a visible notice of the switch, keeping a way to return to apifare without restarting the task.

Silent fallback — swallowing the 402 and presenting another provider's results with no notice — is non-conformant: the user loses both the payment choice and the truth about where results came from. Two rules hold in every mode: never present fallback results as apifare results, and never route around a 403 policy denial or a killed agent token as if it were an outage — that is the account owner's own governance acting, not a failure.

5 · Fixtures — every error class an integration must handle

Success (search)

POST /v1/call/dataforseo · HTTP 200

{
  "result": { "query": "model context protocol", "results": [
    { "title": "…", "url": "https://…", "description": "…", "position": 1 }
  ]},
  "cost_usd": 0.002, "credits_charged": 0.3, "balance": 499.7
}

Insufficient balance

any metered call · HTTP 402 — relay human_readable verbatim, or fall back WITH a visible notice

{
  "error": "PAYMENT_REQUIRED",
  "message": "Balance too low. Top up and retry.",
  "topup_url": "https://apifare.com/topup?ref=<public_ref>",
  "topup_links": { "usd_5_for_500_credits": "…", "usd_20_for_2000_credits": "…" },
  "context": { "doing": "calling the \"scrape\" API", "after_topup": "Retry the same call — it resumes with no other change." },
  "auto_refill": { "enabled": false, "enable_url": "https://apifare.com/mandate?ref=<public_ref>" },
  "human_readable": "… ready-to-relay sentence with the link …",
  "balance": 0.2
}

Policy denial (the owner’s governance acting — never route around it)

HTTP 403 · also covers a killed agent token

{
  "error": "ADAPTER_DENIED",
  "message": "This account's policy denies \"<slug>\" for agent \"<name>\".",
  "agent": "<name>"
}

Rate limited

HTTP 429 · 60 requests/min per token

{ "error": "RATE_LIMITED", "message": "Too many requests. Retry in a minute." }

Provider failure (auto-refunded)

HTTP 502 · branch on the refunded FIELD, never the message text

{
  "error": "PROVIDER_ERROR",
  "message": "Provider call failed and your 0.3 credits were refunded. Retry may succeed.",
  "detail": "<provider status metadata — never bodies>",
  "refunded": true, "refund_credits": 0.3, "balance": 499.7
}

6 · Limits

60 requests/min per token (429, structured). Per-provider circuit breakers can pause a route (503, named, never billed). Per-user daily spend cap 2,000 credits. No separate concurrency cap today; if your router needs more headroom, that is a conversation, not a wall.

7 · Nested budgets (multi-user hosts)

One account can mint a named agent token per user or session (POST /v1/agents), each with its own per-call, daily, and monthly caps, allow/deny lists, and an individual kill switch — enforced on our side before dispatch. Your per-session budgets and ours are the same mechanism at two scopes.

8 · Latency, measured

Architecture: one HTTPS hop plus a policy check and a ledger write at our edge; the dominant cost is always the upstream provider. Measured end-to-end from a standard account over the public internet, 2026-09-19 (5 sequential calls per route; re-measured with each page revision):

routep50rangenote
open-meteo (weather)354 ms344–507 msfast provider — bounds apifare’s own added overhead (edge + policy check + ledger write) at roughly 100–250 ms
scrape (page fetch)803 ms609 ms – 2.0 sprovider-dominated
dataforseo (live Google SERP)3.9 s2.3 – 13.5 sprovider-dominated; live SERPs are slow everywhere

Measure us adversarially — a trial account is free, and we would rather you publish your numbers than trust ours.

9 · Privacy & retention, per component

Request/response bodies: never stored — they pass through memory and are not persisted or logged anywhere; the only retention policy is having nothing to retain. Call metadata (route, price, latency, status) and the append-only ledger/audit chain persist for the account's life. Search-miss text is kept as a demand signal (removable on request). Vaulted keys are AES-256-GCM ciphertext until the user deletes them; no endpoint returns them. Rate-limit IP counters expire within 24 hours. Full policy: /privacy. Upstream providers receive exactly the request your user's agent sent — routed, not enriched.

10 · Maintenance & testing commitment

Claims on this page are CI-pinned or dated-measured. The wire contract is exercised by an external conformance test integrators can run against a funded account (KINDLY_RUN_LIVE_TESTS-style — we will run it on request and paste output). Breaking changes: never without the §2 deprecation policy. Integration bugs reported via POST /v1/support or the repo get same-week responses; our track record is same-day. We will write the adapter PR to your conventions on request.

Version 1 — 2026-09-19. Questions this page fails to answer are bugs in the page: tell us and it gets fixed and versioned.