Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions features/agent.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,118 @@ The `model` parameter is optional — every request runs `spark-2`:

</CodeGroup>

## Data providers that need terms

<Note>Terms gating for Agent is rolling out. Until it's enabled for your runs, `onTermsRequired` has no effect, and none of the fields below appear.</Note>

Agent can call [Alexandria](/features/alexandria) data providers during a run, but only the ones whose data terms your team has accepted. A provider whose terms you haven't accepted is never called, whatever `exchange.onTermsRequired` is set to. The run carries on with the providers it can use, and the status response reports what it skipped.

There is no auto-accept mode. Accepting a provider's terms always needs a person to agree to them, either in the [dashboard](https://www.firecrawl.dev/app/settings?tab=data-sources) or through a `terms/accept` call your application makes after its user has explicitly agreed. If you build an agent on top of Firecrawl, it must ask its user before calling `terms/accept`. A request for data isn't consent to a provider's terms.

| `onTermsRequired` | What happens |
|---|---|
| `skip` (default) | The run answers with accepted providers only and never blocks. `exchange.skippedProviders` lists the gated providers that would have helped. |
| `ask` | The same as `skip`. The run also ends with `exchange.requiresAction` and a `pendingApproval` of `kind: "terms"`, so you can ask your user, accept, and continue the thread. |

If you leave `onTermsRequired` out on a follow-up turn of a thread, the turn uses the previous turn's value. If a turn ends on a paid-call approval (`requireApproval`), it has no terms offer.

### Response fields

These fields are on the `exchange` object of `GET /v2/agent/{id}`:

- `skippedProviders` (any mode): one entry per gated provider that would have helped, with `provider`, `name`, `capability`, `adds` (what it would have added), `reason: "terms_required"`, `version` (the terms version) and `termsUrl` (where to accept in the dashboard).
- `requiresAction` (`ask` only): `type: "accept_terms"`, an `approvalId` and a `providers` list. `approvalId` is always present. It's the id of the `terms` pending approval you answer when you continue the thread. Each provider carries the exact `show` (`terms/show`) and `accept` (`terms/accept`) calls to make. Each provider's `digest` (and `accept.options.digest`) is always present and can be `null`, meaning the catalog didn't publish one. In that case, run `terms/show` first and send the digest it returns.

```json
{
"status": "completed",
"exchange": {
"enabled": true,
"onTermsRequired": "ask",
"paidCalls": 0,
"creditsUsed": null,
"skippedProviders": [
{
"provider": "apollo",
"name": "Apollo",
"capability": "people/search",
"adds": "verified work emails and direct phone numbers",
"reason": "terms_required",
"version": "F-1.0.0",
"termsUrl": "https://www.firecrawl.dev/app/alexandria/apollo"
}
],
"requiresAction": {
"type": "accept_terms",
"approvalId": "0199aaaa-0000-7000-8000-000000000000",
"providers": [
{
"provider": "apollo",
"name": "Apollo",
"capability": "people/search",
"version": "F-1.0.0",
"digest": "<sha256>",
"url": "https://www.firecrawl.dev/app/alexandria/apollo",
"show": { "provider": "firecrawl", "capability": "terms/show", "options": { "provider": "apollo" } },
"accept": {
"provider": "firecrawl",
"capability": "terms/accept",
"options": { "provider": "apollo", "version": "F-1.0.0", "digest": "<sha256>", "confirmed": true }
}
}
]
}
},
"pendingApproval": {
"id": "0199aaaa-0000-7000-8000-000000000000",
"kind": "terms",
"reason": "Apollo could add verified work emails and direct phone numbers.",
"calls": [],
"terms": [{ "provider": "apollo", "name": "Apollo", "version": "F-1.0.0", "digest": "<sha256>", "url": "https://www.firecrawl.dev/app/alexandria/apollo" }],
"resolution": null
}
}
```

### Accept, then continue

In `ask` mode:

1. Show your user the terms. Run the provider's `show` call through [`/v2/scrape`](/features/alexandria) with `alexandria`.
2. Only if the user explicitly agrees, run its `accept` call the same way. If `accept.options.digest` is `null`, use the digest `terms/show` returned:

```bash
curl -X POST https://api.firecrawl.dev/v2/scrape \
-H "Authorization: Bearer $FIRECRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"alexandria": {
"provider": "firecrawl",
"capability": "terms/accept",
"options": { "provider": "apollo", "version": "F-1.0.0", "digest": "<sha256>", "confirmed": true }
}
}'
```

3. Continue the same thread with `exchange.approve`. The offer is accepted as a whole, and `callIds` and `always` are ignored on it. The next turn uses those providers to fill the gap the previous answer named, rather than re-running everything.

```bash
curl -X POST https://api.firecrawl.dev/v2/agent \
-H "Authorization: Bearer $FIRECRAWL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"threadId": "<threadId from the previous run>",
"prompt": "Continue with Apollo.",
"exchange": {
"approve": { "approvalId": "0199aaaa-0000-7000-8000-000000000000" }
}
}'
```

To go on without the provider, continue with `exchange.decline: { "approvalId": "..." }` instead. This declines the whole offer, and its providers aren't offered again for the rest of the thread.

In `skip` mode there's no pending approval to answer. After the terms are accepted, start a new run (or a new turn of the thread) and the provider is available.

## Parameters

| Parameter | Type | Required | Description |
Expand All @@ -260,6 +372,7 @@ The `model` parameter is optional — every request runs `spark-2`:
| `strictConstrainToURLs` | boolean | No | If `true`, the agent only visits the URLs provided in the `urls` array |
| `webhook` | object | No | Webhook to receive agent lifecycle events (`agent.started`, `agent.action`, `agent.completed`, `agent.failed`, `agent.cancelled`). See the [webhook payloads](/api-reference/endpoint/webhook-agent-started) |
| `maxCredits` | number | No | Maximum number of credits to spend on this agent task. Defaults to **2,500** if not set. The dashboard supports values up to **2,500**; for higher limits, set `maxCredits` via the API (values above 2,500 are always treated as paid requests). If the limit is reached, the job fails and **no data is returned**. Failed runs are not billed: credits used for AI reasoning are never charged on failure, any credits used for tool calls during the run (scraping, search, mapping, etc.) are refunded, and the response reports `creditsUsed: 0`. |
| `exchange.onTermsRequired` | string | No | What to do when an Alexandria data provider the agent would use needs terms your team has not accepted: `skip` (default) or `ask`. See [Data providers that need terms](#data-providers-that-need-terms) |

## Agent vs Extract: What's Improved

Expand Down
2 changes: 1 addition & 1 deletion features/alexandria.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ if catalogue.items and catalogue.items[0].get("next"):

- **Tool discovery:** free. Use `sources: ["alexandria"]` for tools only, or `["web", "alexandria"]` to include paid web results.
- **Execution:** charged at the tool's listed price.
- **Provider terms:** a `THIRD_PARTY_DATA_TERMS_REQUIRED` error includes `requiresAction.url`. An org admin must review and accept the terms there. Agents need explicit user authorization before accepting terms.
- **Provider terms:** a `THIRD_PARTY_DATA_TERMS_REQUIRED` error includes `requiresAction.url`. An org admin must review and accept the terms there. Agents need explicit user authorization before accepting terms. [Agent](/features/agent#data-providers-that-need-terms) runs skip providers whose terms your team hasn't accepted and report them in `exchange.skippedProviders`.

<AccordionGroup>
<Accordion title="Find tools for a website">
Expand Down
Loading