Docs: Raw endpoints
API reference

Raw endpoints

Provider + endpoint addressing for the long tail: the provider's own request and payload, settled at cost x 1.43.

Two tiers share one front door. Capabilities are the routed product: one name, normalized input and output, a quote before the run, several providers behind it, waterfall failover. Raw endpoints are the long tail: one provider's own endpoint, called with the provider's own request shape, answered with the provider's own payload. No routing, no normalization, no fixed price.

Use a capability when one exists (discover tells you which capability wraps an endpoint). Use a raw endpoint when you need a provider field the capability does not expose, or a job the catalog has not wrapped yet.

Where they come from

Endpoints are imported from the providers' own catalogs, not hand-written: DataForSEO's OpenAPI specification (every live endpoint plus the free reference data), the Apify store (public actors that allow agentic use and bill per event or per compute, filtered to actors people actually run), and the OpenAPI specifications of TikHub, Exa and Firecrawl. A few providers without a machine-readable catalog have hand-maintained manifests (LeadMagic, Hunter, Tomba, MillionVerifier, PredictLeads, ScrapeCreators).

Some providers are never exposed raw, and inspect says why: fal (its terms prohibit it; use creative.*), Apollo (bring-your-own-key only), AgentMail and Name.com (inboxes and domains live in the platform account and are owned per workspace; use email.* and domain.*).

Each provider page shows how many endpoints it serves. GET /v1/catalog/providers/{provider} carries endpoints.count and endpoints.status: live (runs now), ready (listed, platform account pending), excluded.

Addressing

provider + endpoint

dataforseo + /v3/serp/google/organic/live/advanced. apify + /apidojo/tweet-scraper. tikhub + /api/v1/tiktok/app/v3/fetch_video_comments. The endpoint is the provider's own path; discover and the provider listing return it verbatim.

Discover

POST /v1/discover searches capabilities and endpoints together. Every item has kind (capability or endpoint), a relevance score and a health verdict; capabilities outrank endpoints on equal relevance, and a live capability that wraps an endpoint always ranks above it. Restrict with "kind": "endpoint" or "provider": "dataforseo". Read the response's hints.

routergrowth discover -q "tiktok video comments" --kind endpoint
routergrowth endpoints -p dataforseo -q backlinks     # one provider's list, substring filter

Inspect

{"provider": "dataforseo", "endpoint": "/v3/serp/google/organic/live/advanced"}

Returns the provider's contract: input with pathParams, queryParams, body (properties, required) and bodyType, an example, the cost model, health, wrapped_by (capabilities that call this endpoint), a ready-to-run run.cli, and hints. Apify actors load their input schema from the actor's build on first inspect.

input.bodyType Meaning
task DataForSEO: input is one task object (or an array of up to 10); the request body is the array
actor_input Apify: input is the actor's input object
json the JSON body; on GET endpoints input becomes query parameters

Run

{
  "provider": "dataforseo",
  "endpoint": "/v3/serp/google/organic/live/advanced",
  "input": {"keyword": "best crm", "location_code": 2840, "language_code": "en"},
  "routing": {"max_cost": "0.05"}
}

path fills {placeholders} in the endpoint ({"domain": "example.com"}), query adds query parameters. The response has the run's usual shape with kind: "endpoint", capability: null, endpoint set, and result.data holding the provider's payload untouched (result.raw: true).

How a raw run bills

There is no quote. Instead:

  1. Hold. Before the call, the wallet holds the rate-card estimate x 1.5 when the provider publishes rates, or $1.00 when it does not. routing.max_cost lowers the hold; set it on every raw call.
  2. Settle. After the call, the charge is the provider's measured cost x 1.43 (a 30% margin) when the provider reports its cost (DataForSEO reports every task's cost; Apify reports usageTotalUsd), the rate-card estimate otherwise. The charge never exceeds the hold, and never exceeds max_cost.
  3. Release. Provider errors, timeouts and HTTP 4xx/5xx release the hold in full. A measured cost of zero charges nothing.

Apify actors that bill per event receive your cap directly: the hold divided by the markup becomes the run's maxTotalChargeUsd, enforced by Apify.

Raw runs never fall back to another provider: there is nothing equivalent to fall back to.

Controls

The daily spend guard applies to raw runs like any other. A per-run ceiling exists for exactly this tier: POST /v1/spend-guard {"per_run_limit": "1"} blocks any single run whose hold would exceed $1 (status blocked, error cost_limit_exceeded, a controls list naming the control). It is off unless you enable it; null disables it again.

Health

Every endpoint and every capability offer carries health: healthy (confirmed within the last hour), stable (strong 30-day record), degraded, outage, or unknown (not enough data, common for low-traffic endpoints, not a warning), with the measured success rate, p50 and p95 latency and the sample size. For Apify actors with no measurements of our own, the actor's published 30-day run stats stand in (source: "provider_reported"). Use health to break ties between two endpoints that both fit, never to skip one that is unknown.

Promotion

Raw calls that recur are the roadmap: an endpoint many workspaces call gets wrapped into a routed capability with a fixed price and a second provider behind it. python -m app.ops.endpoints usage is the report.

Reading this as an agent? This page as markdown: /docs/api/endpoints.md · every page: /docs/llms.txt