From 0931c52d65f568cea1025d61709eb1994ec47cec Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 14:02:43 -0400 Subject: [PATCH 01/38] Document Firecrawl Exchange Adds an Exchange page under Core Endpoints covering discovery, invocation, composing provider results into a web search, bring-your-own-key, pricing and per-call errors. English navigation only; locales are managed separately. --- docs.json | 7 ++ features/exchange.mdx | 262 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 features/exchange.mdx diff --git a/docs.json b/docs.json index 02aa16a25..b4e96f223 100755 --- a/docs.json +++ b/docs.json @@ -194,6 +194,13 @@ "features/monitoring-web-scale" ] }, + { + "group": "Exchange", + "icon": "arrow-right-arrow-left", + "pages": [ + "features/exchange" + ] + }, "features/interact" ] }, diff --git a/features/exchange.mdx b/features/exchange.mdx new file mode 100644 index 000000000..597411b14 --- /dev/null +++ b/features/exchange.mdx @@ -0,0 +1,262 @@ +--- +title: "Exchange" +description: "Call approved data providers through one Firecrawl contract" +og:title: "Exchange | Firecrawl" +og:description: "Call approved data providers through one Firecrawl contract" +icon: "arrow-right-arrow-left" +--- + +Firecrawl Exchange gives your agent access to specialist data providers without +integrating each one. Every provider publishes a contract describing what it +returns, what options it takes, and what a call costs. You discover providers +with your Firecrawl API key and call them the same way you call any other +Firecrawl endpoint. + + +Exchange is in beta and access is granted per account. Discovery is free; +credits are charged only when a capability is executed. + + +## How it works + +A provider is a data source. A capability is one thing that provider can do, +such as searching companies or enriching a contact. Each capability publishes a +JSON Schema for its options, a schema for its response, and a price in credits. + + + + Browse providers and capabilities, and read each contract, for zero credits. + + + Call one capability and get a direct, structured result back. + + + Blend provider results into a normal web search in a single request. + + + +## Discover providers + +`GET /v2/exchange` returns the catalog: every published provider, its +categories, and its capabilities. It costs no credits. + + +```bash cURL +curl -X GET "https://api.firecrawl.dev/v2/exchange" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" +``` + + +Drill into one provider, or one capability, by appending its key: + + +```bash cURL +curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" + +curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme/company-search" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" +``` + + +A capability node carries everything needed to call it: + +```json +{ + "kind": "capability", + "provider": "acme", + "id": "company-search", + "operation": "search", + "readOnly": true, + "delivery": "direct", + "creditsPerCall": 25, + "inputSchema": { "type": "object", "properties": { "domain": { "type": "string" } } }, + "outputSchema": { "type": "object" }, + "examples": [{ "kind": "request", "value": { "domain": "firecrawl.dev" } }] +} +``` + +### Reading the catalog as an agent + +Every discovery route also returns Markdown when you ask for it, so an agent can +read a contract as text instead of parsing JSON. + + +```bash cURL +curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme/company-search" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" \ + -H "Accept: text/markdown" +``` + + +The Markdown includes the capability's purpose, when to use it, its cost, and a +ready-to-send request body. + +## Invoke a capability + +`POST /v2/exchange/invoke` executes one or more capabilities and returns their +results directly. Each call needs a `provider`, a `capability`, the `options` +its input schema requires, and an `idempotencyKey` that is unique within the +request. + + +```bash cURL +curl -X POST "https://api.firecrawl.dev/v2/exchange/invoke" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "calls": [ + { + "provider": "acme", + "capability": "company-search", + "options": { "domain": "firecrawl.dev" }, + "idempotencyKey": "acme-firecrawl-dev-1" + } + ] + }' +``` + +```js Node +const result = await firecrawl.exchangeInvoke({ + calls: [ + { + provider: "acme", + capability: "company-search", + options: { domain: "firecrawl.dev" }, + idempotencyKey: "acme-firecrawl-dev-1", + }, + ], +}); +``` + + +The response reports each call separately, so one failure does not discard the +rest: + +```json +{ + "success": true, + "partial": false, + "data": { + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "delivery": "direct", + "creditsCost": 25, + "data": { "company": { "name": "Firecrawl" } } + } + ] + }, + "creditsUsed": 25, + "id": "0198f3c2-..." +} +``` + +`partial` is `true` when some calls succeeded and others failed. A call that +fails carries an `error` object with a `code`, a `message`, and `retryable` +instead of `data`. + + +Reuse the same `idempotencyKey` when retrying the same logical call. Exchange +returns the original result rather than calling the provider and charging twice. + + +## Compose with web search + +`POST /v2/search` accepts an `exchange` array, so one request can return web +results and provider results together. The `query` is optional when at least one +Exchange call is present. + + +```bash cURL +curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "query": "firecrawl funding", + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "options": { "domain": "firecrawl.dev" }, + "idempotencyKey": "acme-firecrawl-dev-2" + } + ] + }' +``` + +```js Node +const result = await firecrawl.search({ + query: "firecrawl funding", + exchange: [ + { + provider: "acme", + capability: "company-search", + options: { domain: "firecrawl.dev" }, + idempotencyKey: "acme-firecrawl-dev-2", + }, + ], +}); +``` + + +Provider results arrive under `data.exchange`, alongside `data.web`, +`data.news`, and `data.images`. + +## Bring your own key + +Some providers are published as bring-your-own-key. You already have an account +with the provider, so you send your own credential and Firecrawl routes the call +without reselling their data. Pass it as `providerApiKey` on the call: + +```json +{ + "provider": "acme", + "capability": "company-search", + "options": { "domain": "firecrawl.dev" }, + "providerApiKey": "$ACME_API_KEY", + "idempotencyKey": "acme-firecrawl-dev-3" +} +``` + +Bring-your-own-key capabilities cost zero Firecrawl credits; the provider bills +you directly. The credential is forwarded to the provider for that one call and +is never stored. + +## Pricing + +Discovery costs nothing. Executing a capability costs the `creditsPerCall` +published in its contract, and you are charged only for calls that succeed. +Check a capability's price before calling it: + + +```bash cURL +curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme/company-search" \ + -H "Authorization: Bearer fc-YOUR_API_KEY" | jq .creditsPerCall +``` + + +## Errors + +Failures are reported per call rather than failing the whole request. + +| Code | Meaning | +| --- | --- | +| `exchange_capability_not_supported` | The capability is not available through the direct beta. | +| `terms_acceptance_required` | Your organization must accept the provider's data terms first. | +| `capability_disabled` | Firecrawl has temporarily disabled this capability. | +| `provider_not_published` | The provider or capability is not published. | +| `byok_credential_required` | The capability needs a `providerApiKey`. | +| `exchange_price_changed` | The published price changed before execution; retry to use the new price. | + +## List your data on Exchange + +If you have an API you want agents to reach, you can publish it as a provider. +Upload an OpenAPI specification and Firecrawl derives your capabilities from it, +then walks you through pricing, categorisation, and ownership verification. +Every listing is reviewed before it becomes public. + + + Start from the Exchange directory in your dashboard. + From 82960ef94523f25b3bdec0f39f4dcdb7f4ed4f50 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 15:56:47 -0400 Subject: [PATCH 02/38] Document Exchange as part of search Exchange has no dedicated endpoint: sources: ["exchange"] finds providers and an exchange array runs them, both on /v2/search. Adds cohort, provider and capability filters, and drops the idempotency key from the basic examples now that it is optional. --- docs.json | 10 +- features/exchange.mdx | 285 ++++++++++++++++++++++++++---------------- 2 files changed, 179 insertions(+), 116 deletions(-) diff --git a/docs.json b/docs.json index b4e96f223..f8a9b98e2 100755 --- a/docs.json +++ b/docs.json @@ -184,6 +184,7 @@ "features/document-parsing" ] }, + "features/interact", { "group": "Monitor", "icon": "radar", @@ -194,14 +195,7 @@ "features/monitoring-web-scale" ] }, - { - "group": "Exchange", - "icon": "arrow-right-arrow-left", - "pages": [ - "features/exchange" - ] - }, - "features/interact" + "features/exchange" ] }, { diff --git a/features/exchange.mdx b/features/exchange.mdx index 597411b14..f20fb779a 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -8,9 +8,10 @@ icon: "arrow-right-arrow-left" Firecrawl Exchange gives your agent access to specialist data providers without integrating each one. Every provider publishes a contract describing what it -returns, what options it takes, and what a call costs. You discover providers -with your Firecrawl API key and call them the same way you call any other -Firecrawl endpoint. +returns, what options it takes, and what a call costs. + +There is no separate Exchange API. You find providers and call them through +`POST /v2/search`, using the same API key as every other Firecrawl request. Exchange is in beta and access is granted per account. Discovery is free; @@ -24,119 +25,179 @@ such as searching companies or enriching a contact. Each capability publishes a JSON Schema for its options, a schema for its response, and a price in credits. - - Browse providers and capabilities, and read each contract, for zero credits. + + Set `sources` to `exchange` to search the catalog. Costs no credits. - - Call one capability and get a direct, structured result back. + + Add an `exchange` array to run a capability and get a structured result. - Blend provider results into a normal web search in a single request. + Return provider results and web results together in one request. -## Discover providers +## Find a provider -`GET /v2/exchange` returns the catalog: every published provider, its -categories, and its capabilities. It costs no credits. +Exchange has no separate catalog endpoint. Set `sources` to `exchange` on +`POST /v2/search` and matching capabilities come back alongside your web +results, shaped like any other result. Discovery costs no credits. -```bash cURL -curl -X GET "https://api.firecrawl.dev/v2/exchange" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" +```js Node +const result = await firecrawl.search({ + query: "company funding data", + sources: ["exchange"], +}); + +for (const provider of result.providers ?? []) { + console.log(provider.title, provider.description); +} ``` - -Drill into one provider, or one capability, by appending its key: +```python Python +result = firecrawl.search({ + "query": "company funding data", + "sources": ["exchange"], +}) - -```bash cURL -curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" +for provider in result.get("providers", []): + print(provider["title"], provider["description"]) +``` -curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme/company-search" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" +```bash cURL +curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "query": "company funding data", + "sources": ["exchange"] + }' ``` -A capability node carries everything needed to call it: +Matches arrive under `data.providers`, each carrying the capability's purpose, +its price, and the call needed to run it: ```json { - "kind": "capability", - "provider": "acme", - "id": "company-search", - "operation": "search", - "readOnly": true, - "delivery": "direct", - "creditsPerCall": 25, - "inputSchema": { "type": "object", "properties": { "domain": { "type": "string" } } }, - "outputSchema": { "type": "object" }, - "examples": [{ "kind": "request", "value": { "domain": "firecrawl.dev" } }] + "providers": [ + { + "url": "https://www.firecrawl.dev/exchange/acme", + "title": "Acme — Company search", + "description": "Find companies by funding stage and location. 25 credits per call. Call with exchange: [{ provider: \"acme\", capability: \"company-search\", options: { ... } }]" + } + ] } ``` -### Reading the catalog as an agent +### Narrowing the search -Every discovery route also returns Markdown when you ask for it, so an agent can -read a contract as text instead of parsing JSON. +Use the object form of the source to scope discovery. `categories` limits it to +a cohort, `providers` to named providers, and `capabilities` to specific +`provider/capability` pairs. They compose, so a cohort plus a provider narrows +further. -```bash cURL -curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme/company-search" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" \ - -H "Accept: text/markdown" -``` - +```js Node +// Only people and finance providers +await firecrawl.search({ + query: "enrich a contact", + sources: [{ type: "exchange", categories: ["people", "finance"] }], +}); -The Markdown includes the capability's purpose, when to use it, its cost, and a -ready-to-send request body. +// Only one provider +await firecrawl.search({ + query: "funding rounds", + sources: [{ type: "exchange", providers: ["acme"] }], +}); -## Invoke a capability +// One named capability +await firecrawl.search({ + query: "funding rounds", + sources: [{ type: "exchange", capabilities: ["acme/company-search"] }], +}); +``` -`POST /v2/exchange/invoke` executes one or more capabilities and returns their -results directly. Each call needs a `provider`, a `capability`, the `options` -its input schema requires, and an `idempotencyKey` that is unique within the -request. +```python Python +result = firecrawl.search({ + "query": "enrich a contact", + "sources": [{"type": "exchange", "categories": ["people", "finance"]}], +}) +``` - ```bash cURL -curl -X POST "https://api.firecrawl.dev/v2/exchange/invoke" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" \ +curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "calls": [ - { - "provider": "acme", - "capability": "company-search", - "options": { "domain": "firecrawl.dev" }, - "idempotencyKey": "acme-firecrawl-dev-1" - } + "query": "enrich a contact", + "sources": [ + { "type": "exchange", "categories": ["people", "finance"] } ] }' ``` + + + +Discovery is additive. If the catalog is unavailable the request still returns +your web results rather than failing. + + +## Call a provider + +Providers are called through `POST /v2/search`. Add an `exchange` array with the +`provider`, the `capability`, and the `options` its input schema requires. + +`query` is optional. Omit it to call providers only, or include it to get web +results and provider results back together in one request. + ```js Node -const result = await firecrawl.exchangeInvoke({ - calls: [ +const result = await firecrawl.search({ + exchange: [ { provider: "acme", capability: "company-search", options: { domain: "firecrawl.dev" }, - idempotencyKey: "acme-firecrawl-dev-1", }, ], }); ``` + +```python Python +result = firecrawl.search({ + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "options": {"domain": "firecrawl.dev"}, + } + ] +}) +``` + +```bash cURL +curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "options": { "domain": "firecrawl.dev" } + } + ] + }' +``` -The response reports each call separately, so one failure does not discard the -rest: +Provider results arrive under `data.exchange`, and each call is reported +separately so one failure does not discard the rest: ```json { "success": true, - "partial": false, "data": { "exchange": [ { @@ -153,25 +214,51 @@ rest: } ``` -`partial` is `true` when some calls succeeded and others failed. A call that -fails carries an `error` object with a `code`, a `message`, and `retryable` -instead of `data`. +A call that fails carries an `error` object with a `code`, a `message`, and +`retryable` instead of `data`. -Reuse the same `idempotencyKey` when retrying the same logical call. Exchange -returns the original result rather than calling the provider and charging twice. +Add an optional `idempotencyKey` to a call to make retries safe. Sending the same +key again returns the original result instead of calling the provider and billing +a second time. Without one, a repeated request re-executes, exactly like a +repeated web search. -## Compose with web search +### Alongside web results -`POST /v2/search` accepts an `exchange` array, so one request can return web -results and provider results together. The `query` is optional when at least one -Exchange call is present. +Include a `query` to get both in one request. Provider results appear under +`data.exchange`, next to `data.web`, `data.news`, and `data.images`. +```js Node +const result = await firecrawl.search({ + query: "firecrawl funding", + exchange: [ + { + provider: "acme", + capability: "company-search", + options: { domain: "firecrawl.dev" }, + }, + ], +}); +``` + +```python Python +result = firecrawl.search({ + "query": "firecrawl funding", + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "options": {"domain": "firecrawl.dev"}, + } + ] +}) +``` + ```bash cURL curl -X POST "https://api.firecrawl.dev/v2/search" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "query": "firecrawl funding", @@ -179,46 +266,31 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ { "provider": "acme", "capability": "company-search", - "options": { "domain": "firecrawl.dev" }, - "idempotencyKey": "acme-firecrawl-dev-2" + "options": { "domain": "firecrawl.dev" } } ] }' ``` + + +## Bring your own key + +Some providers are published as bring-your-own-key. You already have an account +with the provider, so you send your own credential and Firecrawl routes the call +without reselling their data. Pass it as `providerApiKey` on the call: ```js Node const result = await firecrawl.search({ - query: "firecrawl funding", exchange: [ { provider: "acme", capability: "company-search", options: { domain: "firecrawl.dev" }, - idempotencyKey: "acme-firecrawl-dev-2", + providerApiKey: process.env.ACME_API_KEY, }, ], }); ``` - - -Provider results arrive under `data.exchange`, alongside `data.web`, -`data.news`, and `data.images`. - -## Bring your own key - -Some providers are published as bring-your-own-key. You already have an account -with the provider, so you send your own credential and Firecrawl routes the call -without reselling their data. Pass it as `providerApiKey` on the call: - -```json -{ - "provider": "acme", - "capability": "company-search", - "options": { "domain": "firecrawl.dev" }, - "providerApiKey": "$ACME_API_KEY", - "idempotencyKey": "acme-firecrawl-dev-3" -} -``` Bring-your-own-key capabilities cost zero Firecrawl credits; the provider bills you directly. The credential is forwarded to the provider for that one call and @@ -226,16 +298,13 @@ is never stored. ## Pricing -Discovery costs nothing. Executing a capability costs the `creditsPerCall` -published in its contract, and you are charged only for calls that succeed. -Check a capability's price before calling it: +Finding a provider costs nothing. Running a capability costs the +`creditsPerCall` published in its contract, and you are charged only for calls +that succeed. Discovery results carry the price, so you can check before +calling. - -```bash cURL -curl -X GET "https://api.firecrawl.dev/v2/exchange/providers/acme/company-search" \ - -H "Authorization: Bearer fc-YOUR_API_KEY" | jq .creditsPerCall -``` - +Bring-your-own-key capabilities cost zero Firecrawl credits; the provider bills +you directly. ## Errors From fe3fcfc2b807d055f1836d39b555c994196fe216 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 15:58:04 -0400 Subject: [PATCH 03/38] Show ranked discovery results instead of a print loop The example is what the request looks like; the response block does the explaining, including that matches come back best first. --- features/exchange.mdx | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index f20fb779a..f357422bb 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -48,10 +48,6 @@ const result = await firecrawl.search({ query: "company funding data", sources: ["exchange"], }); - -for (const provider of result.providers ?? []) { - console.log(provider.title, provider.description); -} ``` ```python Python @@ -59,9 +55,6 @@ result = firecrawl.search({ "query": "company funding data", "sources": ["exchange"], }) - -for provider in result.get("providers", []): - print(provider["title"], provider["description"]) ``` ```bash cURL @@ -75,8 +68,8 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ ``` -Matches arrive under `data.providers`, each carrying the capability's purpose, -its price, and the call needed to run it: +Matches arrive under `data.providers`, best first. Each carries the capability's +purpose, its price, and the call needed to run it: ```json { @@ -84,12 +77,25 @@ its price, and the call needed to run it: { "url": "https://www.firecrawl.dev/exchange/acme", "title": "Acme — Company search", - "description": "Find companies by funding stage and location. 25 credits per call. Call with exchange: [{ provider: \"acme\", capability: \"company-search\", options: { ... } }]" + "description": "Find companies by funding stage, location, and headcount. 25 credits per call. Call with exchange: [{ provider: \"acme\", capability: \"company-search\", options: { ... } }]" + }, + { + "url": "https://www.firecrawl.dev/exchange/acme", + "title": "Acme — Funding rounds", + "description": "List funding rounds and investors for a company. 25 credits per call. Call with exchange: [{ provider: \"acme\", capability: \"funding-rounds\", options: { ... } }]" + }, + { + "url": "https://www.firecrawl.dev/exchange/northstar", + "title": "Northstar — Company profile", + "description": "Firmographics and ownership for a domain. 15 credits per call. Call with exchange: [{ provider: \"northstar\", capability: \"company-profile\", options: { ... } }]" } ] } ``` +Ranking weights a capability name above a provider blurb that merely mentions +the words, so the closest match to your query comes first. + ### Narrowing the search Use the object form of the source to scope discovery. `categories` limits it to From a4e8376ebc18893c1b599256d673e53336ec65b5 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:03:58 -0400 Subject: [PATCH 04/38] Show one filter example rather than three The prose already names categories, providers and capabilities; the example only needs to show the object form. --- features/exchange.mdx | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index f357422bb..fc7bd36d1 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -105,23 +105,10 @@ further. ```js Node -// Only people and finance providers -await firecrawl.search({ +const result = await firecrawl.search({ query: "enrich a contact", sources: [{ type: "exchange", categories: ["people", "finance"] }], }); - -// Only one provider -await firecrawl.search({ - query: "funding rounds", - sources: [{ type: "exchange", providers: ["acme"] }], -}); - -// One named capability -await firecrawl.search({ - query: "funding rounds", - sources: [{ type: "exchange", capabilities: ["acme/company-search"] }], -}); ``` ```python Python From 58c6f86b3ce22c24bacb98efd7410f3c2787b732 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:05:31 -0400 Subject: [PATCH 05/38] Drop the beta and per-account access note --- features/exchange.mdx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index fc7bd36d1..468832499 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -14,8 +14,7 @@ There is no separate Exchange API. You find providers and call them through `POST /v2/search`, using the same API key as every other Firecrawl request. -Exchange is in beta and access is granted per account. Discovery is free; -credits are charged only when a capability is executed. +Discovery is free; credits are charged only when a capability is executed. ## How it works From 3b1e3e5e1f0192fb2fa7e597e9f6f28c4508a5ce Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:07:42 -0400 Subject: [PATCH 06/38] Expand nested source objects and match the new result description --- features/exchange.mdx | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 468832499..588d55b9b 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -68,7 +68,7 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ Matches arrive under `data.providers`, best first. Each carries the capability's -purpose, its price, and the call needed to run it: +purpose, its price, and the keys needed to run it: ```json { @@ -76,17 +76,17 @@ purpose, its price, and the call needed to run it: { "url": "https://www.firecrawl.dev/exchange/acme", "title": "Acme — Company search", - "description": "Find companies by funding stage, location, and headcount. 25 credits per call. Call with exchange: [{ provider: \"acme\", capability: \"company-search\", options: { ... } }]" + "description": "Find companies by funding stage, location, and headcount. 25 credits per call. Run it with provider \"acme\" and capability \"company-search\"." }, { "url": "https://www.firecrawl.dev/exchange/acme", "title": "Acme — Funding rounds", - "description": "List funding rounds and investors for a company. 25 credits per call. Call with exchange: [{ provider: \"acme\", capability: \"funding-rounds\", options: { ... } }]" + "description": "List funding rounds and investors for a company. 25 credits per call. Run it with provider \"acme\" and capability \"funding-rounds\"." }, { "url": "https://www.firecrawl.dev/exchange/northstar", "title": "Northstar — Company profile", - "description": "Firmographics and ownership for a domain. 15 credits per call. Call with exchange: [{ provider: \"northstar\", capability: \"company-profile\", options: { ... } }]" + "description": "Firmographics and ownership for a domain. 15 credits per call. Run it with provider \"northstar\" and capability \"company-profile\"." } ] } @@ -106,14 +106,24 @@ further. ```js Node const result = await firecrawl.search({ query: "enrich a contact", - sources: [{ type: "exchange", categories: ["people", "finance"] }], + sources: [ + { + type: "exchange", + categories: ["people", "finance"], + }, + ], }); ``` ```python Python result = firecrawl.search({ "query": "enrich a contact", - "sources": [{"type": "exchange", "categories": ["people", "finance"]}], + "sources": [ + { + "type": "exchange", + "categories": ["people", "finance"], + } + ], }) ``` From 336b00baf484149a3b1bdbd007a1f4953bea9b1f Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:16:21 -0400 Subject: [PATCH 07/38] Show provider, capability and creditsPerCall on discovery results --- features/exchange.mdx | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 588d55b9b..02edc07ef 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -68,7 +68,8 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ Matches arrive under `data.providers`, best first. Each carries the capability's -purpose, its price, and the keys needed to run it: +purpose plus `provider`, `capability`, and `creditsPerCall`, so you know the +price before you call: ```json { @@ -76,17 +77,26 @@ purpose, its price, and the keys needed to run it: { "url": "https://www.firecrawl.dev/exchange/acme", "title": "Acme — Company search", - "description": "Find companies by funding stage, location, and headcount. 25 credits per call. Run it with provider \"acme\" and capability \"company-search\"." + "description": "Find companies by funding stage, location, and headcount. 25 credits per call.", + "provider": "acme", + "capability": "company-search", + "creditsPerCall": 25 }, { "url": "https://www.firecrawl.dev/exchange/acme", "title": "Acme — Funding rounds", - "description": "List funding rounds and investors for a company. 25 credits per call. Run it with provider \"acme\" and capability \"funding-rounds\"." + "description": "List funding rounds and investors for a company. 25 credits per call.", + "provider": "acme", + "capability": "funding-rounds", + "creditsPerCall": 25 }, { "url": "https://www.firecrawl.dev/exchange/northstar", "title": "Northstar — Company profile", - "description": "Firmographics and ownership for a domain. 15 credits per call. Run it with provider \"northstar\" and capability \"company-profile\"." + "description": "Firmographics and ownership for a domain. 15 credits per call.", + "provider": "northstar", + "capability": "company-profile", + "creditsPerCall": 15 } ] } From aba7f86465f7e53cbef138e009f8ac310c57a5dd Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:26:12 -0400 Subject: [PATCH 08/38] Restructure Exchange as steps and move errors to the API reference Adds a designed-for-agents section, nests the page under Search, and drops the errors table now that the API reference carries it. --- docs.json | 6 +- features/exchange.mdx | 422 +++++++++++++++++++++--------------------- 2 files changed, 219 insertions(+), 209 deletions(-) diff --git a/docs.json b/docs.json index f8a9b98e2..84418a3c5 100755 --- a/docs.json +++ b/docs.json @@ -165,7 +165,8 @@ "pages": [ "features/search", "features/search-highlights", - "features/research" + "features/research", + "features/exchange" ] }, { @@ -194,8 +195,7 @@ "features/monitoring-website", "features/monitoring-web-scale" ] - }, - "features/exchange" + } ] }, { diff --git a/features/exchange.mdx b/features/exchange.mdx index 02edc07ef..0b79a81d5 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -10,8 +10,8 @@ Firecrawl Exchange gives your agent access to specialist data providers without integrating each one. Every provider publishes a contract describing what it returns, what options it takes, and what a call costs. -There is no separate Exchange API. You find providers and call them through -`POST /v2/search`, using the same API key as every other Firecrawl request. +You find providers and call them through `POST /v2/search`, using the same API +key as every other Firecrawl request. Discovery is free; credits are charged only when a capability is executed. @@ -35,208 +35,231 @@ JSON Schema for its options, a schema for its response, and a price in credits. -## Find a provider - -Exchange has no separate catalog endpoint. Set `sources` to `exchange` on -`POST /v2/search` and matching capabilities come back alongside your web -results, shaped like any other result. Discovery costs no credits. - - -```js Node -const result = await firecrawl.search({ - query: "company funding data", - sources: ["exchange"], -}); -``` - -```python Python -result = firecrawl.search({ - "query": "company funding data", - "sources": ["exchange"], -}) -``` - -```bash cURL -curl -X POST "https://api.firecrawl.dev/v2/search" \ - -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "company funding data", - "sources": ["exchange"] - }' -``` - - -Matches arrive under `data.providers`, best first. Each carries the capability's -purpose plus `provider`, `capability`, and `creditsPerCall`, so you know the -price before you call: - -```json -{ - "providers": [ - { - "url": "https://www.firecrawl.dev/exchange/acme", - "title": "Acme — Company search", - "description": "Find companies by funding stage, location, and headcount. 25 credits per call.", - "provider": "acme", - "capability": "company-search", - "creditsPerCall": 25 - }, - { - "url": "https://www.firecrawl.dev/exchange/acme", - "title": "Acme — Funding rounds", - "description": "List funding rounds and investors for a company. 25 credits per call.", - "provider": "acme", - "capability": "funding-rounds", - "creditsPerCall": 25 - }, - { - "url": "https://www.firecrawl.dev/exchange/northstar", - "title": "Northstar — Company profile", - "description": "Firmographics and ownership for a domain. 15 credits per call.", - "provider": "northstar", - "capability": "company-profile", - "creditsPerCall": 15 - } - ] -} -``` - -Ranking weights a capability name above a provider blurb that merely mentions -the words, so the closest match to your query comes first. - -### Narrowing the search - -Use the object form of the source to scope discovery. `categories` limits it to -a cohort, `providers` to named providers, and `capabilities` to specific -`provider/capability` pairs. They compose, so a cohort plus a provider narrows -further. - - -```js Node -const result = await firecrawl.search({ - query: "enrich a contact", - sources: [ +## Designed for agents + +Exchange is built so an agent can go from "I need this data" to a working call +without a human reading documentation first. + +- **Nothing new to integrate.** Finding and calling both happen on + `POST /v2/search`, with the same API key. An agent that can already search can + already use Exchange. +- **Results read like search results.** A discovered capability has a `url`, a + `title`, and a `description`, so it needs no separate parser. +- **Every capability is self-describing.** A result's `url` resolves to the full + contract as Markdown, including a JSON Schema for its options, so an agent can + build a valid call rather than guessing. +- **The price is known before the call.** `creditsPerCall` is on every result, + so an agent can decide whether the data is worth the spend. +- **Calls are read-only and return directly.** No polling, no callbacks, and + nothing a retry can damage. + +## Using Exchange + + + + Exchange has no separate catalog endpoint. Set `sources` to `exchange` on + `POST /v2/search` and matching capabilities come back alongside your web + results, shaped like any other result. Discovery costs no credits. + + + ```js Node + const result = await firecrawl.search({ + query: "company funding data", + sources: ["exchange"], + }); + ``` + + ```python Python + result = firecrawl.search({ + "query": "company funding data", + "sources": ["exchange"], + }) + ``` + + ```bash cURL + curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "query": "company funding data", + "sources": ["exchange"] + }' + ``` + + + Matches arrive under `data.providers`, best first. The `description` tells you + what the capability does and what it costs, `provider` and `capability` are the + keys you call it with, and the `url` resolves to its full request and response + contract as Markdown: + + ```json { - type: "exchange", - categories: ["people", "finance"], - }, - ], -}); -``` - -```python Python -result = firecrawl.search({ - "query": "enrich a contact", - "sources": [ + "providers": [ + { + "url": "https://www.firecrawl.dev/exchange/providers/acme/company-search", + "title": "Acme — Company search", + "description": "Find companies by funding stage, location, and headcount. 25 credits per call. Fetch the url for the full request and response contract.", + "provider": "acme", + "capability": "company-search", + "creditsPerCall": 25 + }, { - "type": "exchange", - "categories": ["people", "finance"], + "url": "https://www.firecrawl.dev/exchange/providers/acme/funding-rounds", + "title": "Acme — Funding rounds", + "description": "List funding rounds and investors for a company. 25 credits per call. Fetch the url for the full request and response contract.", + "provider": "acme", + "capability": "funding-rounds", + "creditsPerCall": 25 + }, + { + "url": "https://www.firecrawl.dev/exchange/providers/northstar/company-profile", + "title": "Northstar — Company profile", + "description": "Firmographics and ownership for a domain. 15 credits per call. Fetch the url for the full request and response contract.", + "provider": "northstar", + "capability": "company-profile", + "creditsPerCall": 15 } - ], -}) -``` - -```bash cURL -curl -X POST "https://api.firecrawl.dev/v2/search" \ - -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "query": "enrich a contact", - "sources": [ - { "type": "exchange", "categories": ["people", "finance"] } - ] - }' -``` - - - -Discovery is additive. If the catalog is unavailable the request still returns -your web results rather than failing. - - -## Call a provider - -Providers are called through `POST /v2/search`. Add an `exchange` array with the -`provider`, the `capability`, and the `options` its input schema requires. - -`query` is optional. Omit it to call providers only, or include it to get web -results and provider results back together in one request. - - -```js Node -const result = await firecrawl.search({ - exchange: [ - { - provider: "acme", - capability: "company-search", - options: { domain: "firecrawl.dev" }, - }, - ], -}); -``` - -```python Python -result = firecrawl.search({ - "exchange": [ + ] + } + ``` + + Ranking weights a capability name above a provider blurb that merely mentions + the words, so the closest match to your query comes first. + + + + Use the object form of the source to scope discovery. `categories` limits it to + a cohort, `providers` to named providers, and `capabilities` to specific + `provider/capability` pairs. They compose, so a cohort plus a provider narrows + further. + + + ```js Node + const result = await firecrawl.search({ + query: "enrich a contact", + sources: [ + { + type: "exchange", + categories: ["people", "finance"], + }, + ], + }); + ``` + + ```python Python + result = firecrawl.search({ + "query": "enrich a contact", + "sources": [ + { + "type": "exchange", + "categories": ["people", "finance"], + } + ], + }) + ``` + + ```bash cURL + curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "query": "enrich a contact", + "sources": [ + { "type": "exchange", "categories": ["people", "finance"] } + ] + }' + ``` + + + + Discovery is additive. If the catalog is unavailable the request still returns + your web results rather than failing. + + + + + Providers are called through `POST /v2/search`. Add an `exchange` array with the + `provider`, the `capability`, and the `options` its input schema requires. + + `query` is optional. Omit it to call providers only, or include it to get web + results and provider results back together in one request. + + + ```js Node + const result = await firecrawl.search({ + exchange: [ { + provider: "acme", + capability: "company-search", + options: { domain: "firecrawl.dev" }, + }, + ], + }); + ``` + + ```python Python + result = firecrawl.search({ + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "options": {"domain": "firecrawl.dev"}, + } + ] + }) + ``` + + ```bash cURL + curl -X POST "https://api.firecrawl.dev/v2/search" \ + -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ + -H "Content-Type: application/json" \ + -d '{ + "exchange": [ + { "provider": "acme", "capability": "company-search", - "options": {"domain": "firecrawl.dev"}, - } - ] -}) -``` - -```bash cURL -curl -X POST "https://api.firecrawl.dev/v2/search" \ - -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ - -H "Content-Type: application/json" \ - -d '{ - "exchange": [ - { - "provider": "acme", - "capability": "company-search", - "options": { "domain": "firecrawl.dev" } - } - ] - }' -``` - + "options": { "domain": "firecrawl.dev" } + } + ] + }' + ``` + -Provider results arrive under `data.exchange`, and each call is reported -separately so one failure does not discard the rest: + Provider results arrive under `data.exchange`, and each call is reported + separately so one failure does not discard the rest: -```json -{ - "success": true, - "data": { - "exchange": [ - { - "provider": "acme", - "capability": "company-search", - "delivery": "direct", - "creditsCost": 25, - "data": { "company": { "name": "Firecrawl" } } - } - ] - }, - "creditsUsed": 25, - "id": "0198f3c2-..." -} -``` + ```json + { + "success": true, + "data": { + "exchange": [ + { + "provider": "acme", + "capability": "company-search", + "delivery": "direct", + "creditsCost": 25, + "data": { "company": { "name": "Firecrawl" } } + } + ] + }, + "creditsUsed": 25, + "id": "0198f3c2-..." + } + ``` -A call that fails carries an `error` object with a `code`, a `message`, and -`retryable` instead of `data`. + A call that fails carries an `error` object with a `code`, a `message`, and + `retryable` instead of `data`. - -Add an optional `idempotencyKey` to a call to make retries safe. Sending the same -key again returns the original result instead of calling the provider and billing -a second time. Without one, a repeated request re-executes, exactly like a -repeated web search. - + + Add an optional `idempotencyKey` to a call to make retries safe. Sending the same + key again returns the original result instead of calling the provider and billing + a second time. Without one, a repeated request re-executes, exactly like a + repeated web search. + + + -### Alongside web results +## Returning web results too Include a `query` to get both in one request. Provider results appear under `data.exchange`, next to `data.web`, `data.news`, and `data.images`. @@ -318,19 +341,6 @@ calling. Bring-your-own-key capabilities cost zero Firecrawl credits; the provider bills you directly. -## Errors - -Failures are reported per call rather than failing the whole request. - -| Code | Meaning | -| --- | --- | -| `exchange_capability_not_supported` | The capability is not available through the direct beta. | -| `terms_acceptance_required` | Your organization must accept the provider's data terms first. | -| `capability_disabled` | Firecrawl has temporarily disabled this capability. | -| `provider_not_published` | The provider or capability is not published. | -| `byok_credential_required` | The capability needs a `providerApiKey`. | -| `exchange_price_changed` | The published price changed before execution; retry to use the new price. | - ## List your data on Exchange If you have an API you want agents to reach, you can publish it as a provider. From 2e8b63882797c3460e698cae100348eff9fa0ff8 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:27:06 -0400 Subject: [PATCH 09/38] Name real providers when explaining what one is --- features/exchange.mdx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 0b79a81d5..72d93f6eb 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -19,9 +19,10 @@ Discovery is free; credits are charged only when a capability is executed. ## How it works -A provider is a data source. A capability is one thing that provider can do, -such as searching companies or enriching a contact. Each capability publishes a -JSON Schema for its options, a schema for its response, and a price in credits. +A provider is a data source: FullEnrich for professional profiles, Finnhub for +market data, and so on. A capability is one thing that provider can do, such as +enriching a contact or looking up a quote. Each capability publishes a JSON +Schema for its options, a schema for its response, and a price in credits. From 5c74c80cec9d8edf92e82a412b4940050f6d2b27 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 16:45:56 -0400 Subject: [PATCH 10/38] Update exchange.mdx --- features/exchange.mdx | 128 +++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 59 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 72d93f6eb..dab52b1ae 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -6,27 +6,36 @@ og:description: "Call approved data providers through one Firecrawl contract" icon: "arrow-right-arrow-left" --- -Firecrawl Exchange gives your agent access to specialist data providers without -integrating each one. Every provider publishes a contract describing what it -returns, what options it takes, and what a call costs. +Firecrawl Exchange takes your agent beyond the web. Plenty of the data an agent +needs is not on a page at all: it sits behind a specialist API you would +otherwise have to find, sign up for, get a key from, and wire up as its own +service. Exchange puts those providers behind the contract you already use. -You find providers and call them through `POST /v2/search`, using the same API -key as every other Firecrawl request. +You find providers and call them through [`/search`](/api-reference/endpoint/search), with the same API +key as every other Firecrawl request. Every provider publishes a contract +describing what it returns, what options it takes, and what a call costs. -Discovery is free; credits are charged only when a capability is executed. +Searching the catalog adds no credits to a request. Credits are charged when a +capability is executed; a web query alongside it bills as an ordinary search. + + See every supported provider, its capabilities, and what each one costs. + + ## How it works A provider is a data source: FullEnrich for professional profiles, Finnhub for market data, and so on. A capability is one thing that provider can do, such as enriching a contact or looking up a quote. Each capability publishes a JSON -Schema for its options, a schema for its response, and a price in credits. +Schema for its options, a schema for its response, and a price in credits. The +[provider catalogue](https://www.firecrawl.dev/exchange) lists everything +currently available. - Set `sources` to `exchange` to search the catalog. Costs no credits. + Set `sources` to `exchange` to search the catalog. Adds no credits. Add an `exchange` array to run a capability and get a structured result. @@ -36,31 +45,13 @@ Schema for its options, a schema for its response, and a price in credits. -## Designed for agents - -Exchange is built so an agent can go from "I need this data" to a working call -without a human reading documentation first. - -- **Nothing new to integrate.** Finding and calling both happen on - `POST /v2/search`, with the same API key. An agent that can already search can - already use Exchange. -- **Results read like search results.** A discovered capability has a `url`, a - `title`, and a `description`, so it needs no separate parser. -- **Every capability is self-describing.** A result's `url` resolves to the full - contract as Markdown, including a JSON Schema for its options, so an agent can - build a valid call rather than guessing. -- **The price is known before the call.** `creditsPerCall` is on every result, - so an agent can decide whether the data is worth the spend. -- **Calls are read-only and return directly.** No polling, no callbacks, and - nothing a retry can damage. - ## Using Exchange Exchange has no separate catalog endpoint. Set `sources` to `exchange` on - `POST /v2/search` and matching capabilities come back alongside your web - results, shaped like any other result. Discovery costs no credits. + [`/search`](/api-reference/endpoint/search) and matching capabilities come back alongside your web + results, shaped like any other result. Searching the catalog adds no credits. ```js Node @@ -104,14 +95,6 @@ without a human reading documentation first. "capability": "company-search", "creditsPerCall": 25 }, - { - "url": "https://www.firecrawl.dev/exchange/providers/acme/funding-rounds", - "title": "Acme — Funding rounds", - "description": "List funding rounds and investors for a company. 25 credits per call. Fetch the url for the full request and response contract.", - "provider": "acme", - "capability": "funding-rounds", - "creditsPerCall": 25 - }, { "url": "https://www.firecrawl.dev/exchange/providers/northstar/company-profile", "title": "Northstar — Company profile", @@ -126,6 +109,9 @@ without a human reading documentation first. Ranking weights a capability name above a provider blurb that merely mentions the words, so the closest match to your query comes first. + + To see the full list rather than search it, browse the + [provider catalogue](https://www.firecrawl.dev/exchange). @@ -134,10 +120,12 @@ without a human reading documentation first. `provider/capability` pairs. They compose, so a cohort plus a provider narrows further. + Filters work with or without a query. Drop the query to browse everything in a + cohort; add one to rank within it. + ```js Node const result = await firecrawl.search({ - query: "enrich a contact", sources: [ { type: "exchange", @@ -149,7 +137,6 @@ without a human reading documentation first. ```python Python result = firecrawl.search({ - "query": "enrich a contact", "sources": [ { "type": "exchange", @@ -179,7 +166,7 @@ without a human reading documentation first. - Providers are called through `POST /v2/search`. Add an `exchange` array with the + Providers are called through [`/search`](/api-reference/endpoint/search). Add an `exchange` array with the `provider`, the `capability`, and the `options` its input schema requires. `query` is optional. Omit it to call providers only, or include it to get web @@ -260,35 +247,50 @@ without a human reading documentation first. -## Returning web results too +## One call, many providers -Include a `query` to get both in one request. Provider results appear under -`data.exchange`, next to `data.web`, `data.news`, and `data.images`. +The `exchange` array takes up to ten calls, and a `query` runs a web search +alongside them. So a single request can enrich a contact, pull a market quote, +and search the web at once. Each call is reported separately, so one failure +does not discard the others. ```js Node const result = await firecrawl.search({ - query: "firecrawl funding", + query: "acme corp recent coverage", exchange: [ { - provider: "acme", - capability: "company-search", - options: { domain: "firecrawl.dev" }, + provider: "fullenrich", + capability: "contact-enrichment", + options: { person: { linkedin_url: "https://linkedin.com/in/jane-doe" } }, + }, + { + provider: "finnhub", + capability: "quote", + options: { symbol: "ACME" }, }, ], }); + +result.web; // web results +result.exchange; // one entry per provider call ``` ```python Python result = firecrawl.search({ - "query": "firecrawl funding", + "query": "acme corp recent coverage", "exchange": [ { - "provider": "acme", - "capability": "company-search", - "options": {"domain": "firecrawl.dev"}, - } - ] + "provider": "fullenrich", + "capability": "contact-enrichment", + "options": {"person": {"linkedin_url": "https://linkedin.com/in/jane-doe"}}, + }, + { + "provider": "finnhub", + "capability": "quote", + "options": {"symbol": "ACME"}, + }, + ], }) ``` @@ -297,23 +299,31 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "firecrawl funding", + "query": "acme corp recent coverage", "exchange": [ { - "provider": "acme", - "capability": "company-search", - "options": { "domain": "firecrawl.dev" } + "provider": "fullenrich", + "capability": "contact-enrichment", + "options": { "person": { "linkedin_url": "https://linkedin.com/in/jane-doe" } } + }, + { + "provider": "finnhub", + "capability": "quote", + "options": { "symbol": "ACME" } } ] }' ``` +Provider results arrive under `data.exchange`, next to `data.web`, `data.news`, +and `data.images`. + ## Bring your own key Some providers are published as bring-your-own-key. You already have an account -with the provider, so you send your own credential and Firecrawl routes the call -without reselling their data. Pass it as `providerApiKey` on the call: +with the provider, so you send your own credential and Firecrawl routes the +call. Pass it as `providerApiKey` on the call: ```js Node const result = await firecrawl.search({ @@ -334,7 +344,7 @@ is never stored. ## Pricing -Finding a provider costs nothing. Running a capability costs the +Searching the catalog adds no credits. Running a capability costs the `creditsPerCall` published in its contract, and you are charged only for calls that succeed. Discovery results carry the price, so you can check before calling. From dad606e60caff3a005f30bd78d6d00cc482e5ab5 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:31:57 -0400 Subject: [PATCH 11/38] Drop the idempotency key from the Exchange page --- features/exchange.mdx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index dab52b1ae..c304e6de4 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -237,13 +237,6 @@ currently available. A call that fails carries an `error` object with a `code`, a `message`, and `retryable` instead of `data`. - - - Add an optional `idempotencyKey` to a call to make retries safe. Sending the same - key again returns the original result instead of calling the provider and billing - a second time. Without one, a repeated request re-executes, exactly like a - repeated web search. - From 2c0b0648495b82aaf84d8af75bae41abdaff613b Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 20:54:07 -0400 Subject: [PATCH 12/38] Wrap long lines in the Exchange result examples The description strings ran to 164 characters, forcing a horizontal scroll to read a field the page is explaining. Also drops the note about discovery being additive. --- features/exchange.mdx | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index c304e6de4..cb9e1e5c6 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -84,7 +84,7 @@ currently available. keys you call it with, and the `url` resolves to its full request and response contract as Markdown: - ```json + ```json wrap { "providers": [ { @@ -158,11 +158,6 @@ currently available. }' ``` - - - Discovery is additive. If the catalog is unavailable the request still returns - your web results rather than failing. - @@ -216,7 +211,7 @@ currently available. Provider results arrive under `data.exchange`, and each call is reported separately so one failure does not discard the rest: - ```json + ```json wrap { "success": true, "data": { From 52ce37cc35ae5ced4b892b24861f7eba5181a4ad Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 20:55:54 -0400 Subject: [PATCH 13/38] Use market data for the Exchange walkthrough and drop BYOK The call example enriched a company while the discovery step above it returned company search, so the steps read as two unrelated stories. Uses one market-data provider end to end instead. Removes the bring-your-own-key section until it is ready to document. --- features/exchange.mdx | 88 +++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 57 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index cb9e1e5c6..933473b60 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -56,14 +56,14 @@ currently available. ```js Node const result = await firecrawl.search({ - query: "company funding data", + query: "market data", sources: ["exchange"], }); ``` ```python Python result = firecrawl.search({ - "query": "company funding data", + "query": "market data", "sources": ["exchange"], }) ``` @@ -73,7 +73,7 @@ currently available. -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "company funding data", + "query": "market data", "sources": ["exchange"] }' ``` @@ -88,19 +88,19 @@ currently available. { "providers": [ { - "url": "https://www.firecrawl.dev/exchange/providers/acme/company-search", - "title": "Acme — Company search", - "description": "Find companies by funding stage, location, and headcount. 25 credits per call. Fetch the url for the full request and response contract.", - "provider": "acme", - "capability": "company-search", + "url": "https://www.firecrawl.dev/exchange/providers/finnhub/quote", + "title": "Finnhub — Quote", + "description": "Latest price, daily change, and volume for a listed symbol. 25 credits per call. Fetch the url for the full request and response contract.", + "provider": "finnhub", + "capability": "quote", "creditsPerCall": 25 }, { - "url": "https://www.firecrawl.dev/exchange/providers/northstar/company-profile", - "title": "Northstar — Company profile", - "description": "Firmographics and ownership for a domain. 15 credits per call. Fetch the url for the full request and response contract.", - "provider": "northstar", - "capability": "company-profile", + "url": "https://www.firecrawl.dev/exchange/providers/finnhub/company-fundamentals", + "title": "Finnhub — Company fundamentals", + "description": "Revenue, margins, and reported earnings for a listed company. 15 credits per call. Fetch the url for the full request and response contract.", + "provider": "finnhub", + "capability": "company-fundamentals", "creditsPerCall": 15 } ] @@ -172,9 +172,9 @@ currently available. const result = await firecrawl.search({ exchange: [ { - provider: "acme", - capability: "company-search", - options: { domain: "firecrawl.dev" }, + provider: "finnhub", + capability: "quote", + options: { symbol: "NVDA" }, }, ], }); @@ -184,9 +184,9 @@ currently available. result = firecrawl.search({ "exchange": [ { - "provider": "acme", - "capability": "company-search", - "options": {"domain": "firecrawl.dev"}, + "provider": "finnhub", + "capability": "quote", + "options": {"symbol": "NVDA"}, } ] }) @@ -199,9 +199,9 @@ currently available. -d '{ "exchange": [ { - "provider": "acme", - "capability": "company-search", - "options": { "domain": "firecrawl.dev" } + "provider": "finnhub", + "capability": "quote", + "options": { "symbol": "NVDA" } } ] }' @@ -217,11 +217,11 @@ currently available. "data": { "exchange": [ { - "provider": "acme", - "capability": "company-search", + "provider": "finnhub", + "capability": "quote", "delivery": "direct", "creditsCost": 25, - "data": { "company": { "name": "Firecrawl" } } + "data": { "symbol": "NVDA", "price": 184.62, "change": 2.14, "volume": 41295300 } } ] }, @@ -245,7 +245,7 @@ does not discard the others. ```js Node const result = await firecrawl.search({ - query: "acme corp recent coverage", + query: "nvidia earnings coverage", exchange: [ { provider: "fullenrich", @@ -255,7 +255,7 @@ const result = await firecrawl.search({ { provider: "finnhub", capability: "quote", - options: { symbol: "ACME" }, + options: { symbol: "NVDA" }, }, ], }); @@ -266,7 +266,7 @@ result.exchange; // one entry per provider call ```python Python result = firecrawl.search({ - "query": "acme corp recent coverage", + "query": "nvidia earnings coverage", "exchange": [ { "provider": "fullenrich", @@ -276,7 +276,7 @@ result = firecrawl.search({ { "provider": "finnhub", "capability": "quote", - "options": {"symbol": "ACME"}, + "options": {"symbol": "NVDA"}, }, ], }) @@ -287,7 +287,7 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "acme corp recent coverage", + "query": "nvidia earnings coverage", "exchange": [ { "provider": "fullenrich", @@ -297,7 +297,7 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ { "provider": "finnhub", "capability": "quote", - "options": { "symbol": "ACME" } + "options": { "symbol": "NVDA" } } ] }' @@ -307,29 +307,6 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ Provider results arrive under `data.exchange`, next to `data.web`, `data.news`, and `data.images`. -## Bring your own key - -Some providers are published as bring-your-own-key. You already have an account -with the provider, so you send your own credential and Firecrawl routes the -call. Pass it as `providerApiKey` on the call: - -```js Node -const result = await firecrawl.search({ - exchange: [ - { - provider: "acme", - capability: "company-search", - options: { domain: "firecrawl.dev" }, - providerApiKey: process.env.ACME_API_KEY, - }, - ], -}); -``` - -Bring-your-own-key capabilities cost zero Firecrawl credits; the provider bills -you directly. The credential is forwarded to the provider for that one call and -is never stored. - ## Pricing Searching the catalog adds no credits. Running a capability costs the @@ -337,9 +314,6 @@ Searching the catalog adds no credits. Running a capability costs the that succeed. Discovery results carry the price, so you can check before calling. -Bring-your-own-key capabilities cost zero Firecrawl credits; the provider bills -you directly. - ## List your data on Exchange If you have an API you want agents to reach, you can publish it as a provider. From 368bbd4835245312eb5d8f7ecbfd5cf960a70f9d Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 21:01:57 -0400 Subject: [PATCH 14/38] Build the Exchange page around one Apple research task The steps each demonstrated a different thing, so the page read as unrelated snippets. Now discovery surfaces the company and people providers, the single call uses one of them, and the final example composes both with a web news search into one request. Every provider, capability, and option name is taken from the live catalog rather than invented: the earlier examples used a market-data provider that is not listed and option names the input schemas reject. --- features/exchange.mdx | 185 ++++++++++++++++++++++++++++-------------- 1 file changed, 126 insertions(+), 59 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 933473b60..12a46f7f6 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -26,9 +26,9 @@ capability is executed; a web query alongside it bills as an ordinary search. ## How it works -A provider is a data source: FullEnrich for professional profiles, Finnhub for -market data, and so on. A capability is one thing that provider can do, such as -enriching a contact or looking up a quote. Each capability publishes a JSON +A provider is a data source: Crunchbase for company and funding records, Apollo +for people, and so on. A capability is one thing that provider can do, such as +searching organizations or finding a person by title. Each capability publishes a JSON Schema for its options, a schema for its response, and a price in credits. The [provider catalogue](https://www.firecrawl.dev/exchange) lists everything currently available. @@ -56,14 +56,14 @@ currently available. ```js Node const result = await firecrawl.search({ - query: "market data", + query: "company profile and people at that company", sources: ["exchange"], }); ``` ```python Python result = firecrawl.search({ - "query": "market data", + "query": "company profile and people at that company", "sources": ["exchange"], }) ``` @@ -73,7 +73,7 @@ currently available. -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "market data", + "query": "company profile and people at that company", "sources": ["exchange"] }' ``` @@ -88,20 +88,20 @@ currently available. { "providers": [ { - "url": "https://www.firecrawl.dev/exchange/providers/finnhub/quote", - "title": "Finnhub — Quote", - "description": "Latest price, daily change, and volume for a listed symbol. 25 credits per call. Fetch the url for the full request and response contract.", - "provider": "finnhub", - "capability": "quote", + "url": "https://www.firecrawl.dev/exchange/providers/crunchbase/company-search", + "title": "Crunchbase — Search organizations", + "description": "Find companies with structured firmographic and funding filters. 25 credits per call. Fetch the url for the full request and response contract.", + "provider": "crunchbase", + "capability": "company-search", "creditsPerCall": 25 }, { - "url": "https://www.firecrawl.dev/exchange/providers/finnhub/company-fundamentals", - "title": "Finnhub — Company fundamentals", - "description": "Revenue, margins, and reported earnings for a listed company. 15 credits per call. Fetch the url for the full request and response contract.", - "provider": "finnhub", - "capability": "company-fundamentals", - "creditsPerCall": 15 + "url": "https://www.firecrawl.dev/exchange/providers/apollo/people-search", + "title": "Apollo — Search people", + "description": "Find net-new prospects using title, seniority, location, and organization filters. 25 credits per call. Fetch the url for the full request and response contract.", + "provider": "apollo", + "capability": "people-search", + "creditsPerCall": 25 } ] } @@ -172,9 +172,9 @@ currently available. const result = await firecrawl.search({ exchange: [ { - provider: "finnhub", - capability: "quote", - options: { symbol: "NVDA" }, + provider: "crunchbase", + capability: "company-search", + options: { query: "Apple", limit: 1 }, }, ], }); @@ -184,9 +184,9 @@ currently available. result = firecrawl.search({ "exchange": [ { - "provider": "finnhub", - "capability": "quote", - "options": {"symbol": "NVDA"}, + "provider": "crunchbase", + "capability": "company-search", + "options": {"query": "Apple", "limit": 1}, } ] }) @@ -199,9 +199,9 @@ currently available. -d '{ "exchange": [ { - "provider": "finnhub", - "capability": "quote", - "options": { "symbol": "NVDA" } + "provider": "crunchbase", + "capability": "company-search", + "options": { "query": "Apple", "limit": 1 } } ] }' @@ -217,11 +217,15 @@ currently available. "data": { "exchange": [ { - "provider": "finnhub", - "capability": "quote", + "provider": "crunchbase", + "capability": "company-search", "delivery": "direct", "creditsCost": 25, - "data": { "symbol": "NVDA", "price": 184.62, "change": 2.14, "volume": 41295300 } + "data": { + "organizations": [ + { "name": "Apple", "permalink": "apple", "founded_on": "1976-04-01" } + ] + } } ] }, @@ -235,48 +239,61 @@ currently available. -## One call, many providers +## Putting it together + +Each step so far did one thing. The point of Exchange is that they compose: the +`exchange` array takes up to ten calls, and a `query` runs a web search +alongside them. -The `exchange` array takes up to ten calls, and a `query` runs a web search -alongside them. So a single request can enrich a contact, pull a market quote, -and search the web at once. Each call is reported separately, so one failure -does not discard the others. +So a question like *"tell me about Apple, who runs AI there, and what is being +written about it"* is one request across three sources — the company from one +provider, the person from another, and news from the web. ```js Node const result = await firecrawl.search({ - query: "nvidia earnings coverage", + query: "apple ai strategy", + sources: ["news"], exchange: [ { - provider: "fullenrich", - capability: "contact-enrichment", - options: { person: { linkedin_url: "https://linkedin.com/in/jane-doe" } }, + provider: "crunchbase", + capability: "company-search", + options: { query: "Apple", limit: 1 }, }, { - provider: "finnhub", - capability: "quote", - options: { symbol: "NVDA" }, + provider: "apollo", + capability: "people-search", + options: { + query: "Head of AI at Apple", + filters: { titles: ["Head of AI", "VP Artificial Intelligence"] }, + limit: 5, + }, }, ], }); -result.web; // web results -result.exchange; // one entry per provider call +result.news; // coverage from the web +result.exchange; // the company and the people, in call order ``` ```python Python result = firecrawl.search({ - "query": "nvidia earnings coverage", + "query": "apple ai strategy", + "sources": ["news"], "exchange": [ { - "provider": "fullenrich", - "capability": "contact-enrichment", - "options": {"person": {"linkedin_url": "https://linkedin.com/in/jane-doe"}}, + "provider": "crunchbase", + "capability": "company-search", + "options": {"query": "Apple", "limit": 1}, }, { - "provider": "finnhub", - "capability": "quote", - "options": {"symbol": "NVDA"}, + "provider": "apollo", + "capability": "people-search", + "options": { + "query": "Head of AI at Apple", + "filters": {"titles": ["Head of AI", "VP Artificial Intelligence"]}, + "limit": 5, + }, }, ], }) @@ -287,25 +304,75 @@ curl -X POST "https://api.firecrawl.dev/v2/search" \ -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "nvidia earnings coverage", + "query": "apple ai strategy", + "sources": ["news"], "exchange": [ { - "provider": "fullenrich", - "capability": "contact-enrichment", - "options": { "person": { "linkedin_url": "https://linkedin.com/in/jane-doe" } } + "provider": "crunchbase", + "capability": "company-search", + "options": { "query": "Apple", "limit": 1 } }, { - "provider": "finnhub", - "capability": "quote", - "options": { "symbol": "NVDA" } + "provider": "apollo", + "capability": "people-search", + "options": { + "query": "Head of AI at Apple", + "filters": { "titles": ["Head of AI", "VP Artificial Intelligence"] }, + "limit": 5 + } } ] }' ``` -Provider results arrive under `data.exchange`, next to `data.web`, `data.news`, -and `data.images`. +Provider results arrive under `data.exchange` in the order they were sent, next +to `data.news` and the other web sources. Each call is reported separately, so +one provider failing does not discard the rest: + +```json wrap +{ + "success": true, + "data": { + "news": [ + { + "url": "https://www.example.com/apple-ai-roadmap", + "title": "Apple details its on-device AI roadmap", + "date": "2026-07-29" + } + ], + "exchange": [ + { + "provider": "crunchbase", + "capability": "company-search", + "delivery": "direct", + "creditsCost": 25, + "data": { + "organizations": [ + { "name": "Apple", "permalink": "apple", "founded_on": "1976-04-01" } + ] + } + }, + { + "provider": "apollo", + "capability": "people-search", + "delivery": "direct", + "creditsCost": 25, + "data": { + "people": [ + { "name": "Jane Doe", "title": "Head of AI", "organization": "Apple" } + ] + } + } + ] + }, + "creditsUsed": 51, + "id": "0198f3c2-..." +} +``` + +The web search bills as an ordinary search and each capability bills its own +`creditsPerCall`, so the cost of the whole request is the sum of its parts. ## Pricing From df51c10af0dbd2e2cc8e76e4c6d4053fd895ff02 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 21:07:03 -0400 Subject: [PATCH 15/38] Frame the Exchange page around the outcome, not the mechanics The page introduced features in order and left the reader to imagine why they mattered. It now opens with a concrete brief, names what it costs to assemble that today, and each step moves toward it: ask who can answer, narrow, get the answer, then compose the whole thing in one request. --- features/exchange.mdx | 68 +++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 12a46f7f6..972eef5bd 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -6,14 +6,17 @@ og:description: "Call approved data providers through one Firecrawl contract" icon: "arrow-right-arrow-left" --- -Firecrawl Exchange takes your agent beyond the web. Plenty of the data an agent -needs is not on a page at all: it sits behind a specialist API you would -otherwise have to find, sign up for, get a key from, and wire up as its own -service. Exchange puts those providers behind the contract you already use. +Say your agent needs to brief you on Apple: what the company is, who runs AI +there, and what is being written about it right now. -You find providers and call them through [`/search`](/api-reference/endpoint/search), with the same API -key as every other Firecrawl request. Every provider publishes a contract -describing what it returns, what options it takes, and what a call costs. +Search the web and you get articles *about* those things. The company record +lives in Crunchbase, the person lives in Apollo, and reaching either one +normally means finding the vendor, signing up, getting a key, learning their +schema, and running it as its own service. Three answers, three integrations. + +Exchange puts those providers behind the contract you already use. The same +[`/search`](/api-reference/endpoint/search) call, the same API key. By the end +of this page that brief is a single request. Searching the catalog adds no credits to a request. Credits are charged when a @@ -28,8 +31,9 @@ capability is executed; a web query alongside it bills as an ordinary search. A provider is a data source: Crunchbase for company and funding records, Apollo for people, and so on. A capability is one thing that provider can do, such as -searching organizations or finding a person by title. Each capability publishes a JSON -Schema for its options, a schema for its response, and a price in credits. The +searching organizations or finding a person by title. Each capability publishes a +JSON Schema for its options, a schema for its response, and a price in credits, +so an agent can build a valid call and know the cost before it commits. The [provider catalogue](https://www.firecrawl.dev/exchange) lists everything currently available. @@ -45,25 +49,26 @@ currently available. -## Using Exchange +## Building the brief - - Exchange has no separate catalog endpoint. Set `sources` to `exchange` on - [`/search`](/api-reference/endpoint/search) and matching capabilities come back alongside your web - results, shaped like any other result. Searching the catalog adds no credits. + + Your agent does not need to know Crunchbase or Apollo exist. Describe what + you are after and set `sources` to `exchange`: matching capabilities come + back alongside your web results, shaped like any other result. There is no + separate catalog endpoint, and searching it adds no credits. ```js Node const result = await firecrawl.search({ - query: "company profile and people at that company", + query: "find a company and the people who run it", sources: ["exchange"], }); ``` ```python Python result = firecrawl.search({ - "query": "company profile and people at that company", + "query": "find a company and the people who run it", "sources": ["exchange"], }) ``` @@ -73,7 +78,7 @@ currently available. -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "company profile and people at that company", + "query": "find a company and the people who run it", "sources": ["exchange"] }' ``` @@ -114,11 +119,11 @@ currently available. [provider catalogue](https://www.firecrawl.dev/exchange). - - Use the object form of the source to scope discovery. `categories` limits it to - a cohort, `providers` to named providers, and `capabilities` to specific - `provider/capability` pairs. They compose, so a cohort plus a provider narrows - further. + + When you already know the shape of the answer, say so. Use the object form of + the source to scope discovery: `categories` limits it to a cohort, `providers` + to named providers, and `capabilities` to specific `provider/capability` + pairs. They compose, so a cohort plus a provider narrows further. Filters work with or without a query. Drop the query to browse everything in a cohort; add one to rank within it. @@ -160,8 +165,9 @@ currently available. - - Providers are called through [`/search`](/api-reference/endpoint/search). Add an `exchange` array with the + + Now fetch the company itself. Providers are called through + [`/search`](/api-reference/endpoint/search): add an `exchange` array with the `provider`, the `capability`, and the `options` its input schema requires. `query` is optional. Omit it to call providers only, or include it to get web @@ -239,15 +245,15 @@ currently available. -## Putting it together +## The whole brief, one request -Each step so far did one thing. The point of Exchange is that they compose: the -`exchange` array takes up to ten calls, and a `query` runs a web search -alongside them. +Each step so far answered one part. They compose: the `exchange` array takes up +to ten calls, and a `query` runs a web search alongside them. -So a question like *"tell me about Apple, who runs AI there, and what is being -written about it"* is one request across three sources — the company from one -provider, the person from another, and news from the web. +So the brief we started with — what Apple is, who runs AI there, and what is +being written about it — is one request across three sources. The company from +Crunchbase, the person from Apollo, the coverage from the web. No extra +accounts, no second endpoint, nothing to reconcile afterwards. ```js Node From 954e49386bb84fb125859dc1b9eeef55d7665489 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 21:28:22 -0400 Subject: [PATCH 16/38] Open the Exchange page on triaging an inbound lead Frames the page on a concrete job with stakes rather than a generic company-and-people lookup, and each step answers one part of it. Also stops the discovery example claiming to be live ranking output. It is trimmed to the two capabilities the page uses, and the guidance now says matching is lexical: naming the data ranks well, describing the situation does not. --- features/exchange.mdx | 45 +++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/features/exchange.mdx b/features/exchange.mdx index 972eef5bd..1fae90c86 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -6,17 +6,21 @@ og:description: "Call approved data providers through one Firecrawl contract" icon: "arrow-right-arrow-left" --- -Say your agent needs to brief you on Apple: what the company is, who runs AI -there, and what is being written about it right now. +An inbound lead lands from someone at Apple. Before anyone replies, your agent +needs three things the web will not give you cleanly: -Search the web and you get articles *about* those things. The company record -lives in Crunchbase, the person lives in Apollo, and reaching either one +1. Is the company real, funded, and how big? +2. Who actually owns AI there? +3. What has shipped in the last month? + +The first answer lives in a company database, the second in a contact database, +and only the third is really on the open web. Reaching either of the first two normally means finding the vendor, signing up, getting a key, learning their schema, and running it as its own service. Three answers, three integrations. -Exchange puts those providers behind the contract you already use. The same +Exchange puts those providers behind the contract you already use: the same [`/search`](/api-reference/endpoint/search) call, the same API key. By the end -of this page that brief is a single request. +of this page, triaging that lead is a single request. Searching the catalog adds no credits to a request. Credits are charged when a @@ -53,22 +57,22 @@ currently available. - Your agent does not need to know Crunchbase or Apollo exist. Describe what - you are after and set `sources` to `exchange`: matching capabilities come - back alongside your web results, shaped like any other result. There is no - separate catalog endpoint, and searching it adds no credits. + Your agent does not need to know Crunchbase or Apollo exist. Name the data it + needs and set `sources` to `exchange`: matching capabilities come back + alongside your web results, shaped like any other result. There is no separate + catalog endpoint, and searching it adds no credits. ```js Node const result = await firecrawl.search({ - query: "find a company and the people who run it", + query: "company funding and people by title", sources: ["exchange"], }); ``` ```python Python result = firecrawl.search({ - "query": "find a company and the people who run it", + "query": "company funding and people by title", "sources": ["exchange"], }) ``` @@ -78,16 +82,17 @@ currently available. -H "Authorization: Bearer $FIRECRAWL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ - "query": "find a company and the people who run it", + "query": "company funding and people by title", "sources": ["exchange"] }' ``` - Matches arrive under `data.providers`, best first. The `description` tells you - what the capability does and what it costs, `provider` and `capability` are the - keys you call it with, and the `url` resolves to its full request and response - contract as Markdown: + Matches arrive under `data.providers`, ranked. The `description` tells you what + the capability does and what it costs, `provider` and `capability` are the keys + you call it with, and the `url` resolves to its full request and response + contract as Markdown. A response looks like this, trimmed to the two + capabilities this page goes on to use: ```json wrap { @@ -113,9 +118,11 @@ currently available. ``` Ranking weights a capability name above a provider blurb that merely mentions - the words, so the closest match to your query comes first. + the words. Matching is lexical, so name the data you want rather than the + situation you are in: "company funding" and "people by title" rank well, + "research this lead for me" does not. - To see the full list rather than search it, browse the + To see everything available rather than search it, browse the [provider catalogue](https://www.firecrawl.dev/exchange). From 914020ee49db96bacc4a3694dc83215df64b4df8 Mon Sep 17 00:00:00 2001 From: Developers Digest <124798203+developersdigest@users.noreply.github.com> Date: Fri, 31 Jul 2026 21:37:27 -0400 Subject: [PATCH 17/38] Add an animated agent demo to the top of the Exchange page A self-contained iframe showing an agent answering a question with one Exchange request: it streams in character by character, counts elapsed time while the providers run, and tallies credits as results land. Three switchable use cases (firmographic, finance, news), each using capabilities and prices taken from the live catalog. Sandboxed to allow-scripts only, with no network access and no external assets. --- features/exchange.mdx | 170 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/features/exchange.mdx b/features/exchange.mdx index 1fae90c86..6d0afa56f 100644 --- a/features/exchange.mdx +++ b/features/exchange.mdx @@ -6,6 +6,176 @@ og:description: "Call approved data providers through one Firecrawl contract" icon: "arrow-right-arrow-left" --- +