# Functions

One HTTP call, one result: a screenshot, a PDF, the page as Markdown or its raw HTML and network calls — rendered by a real browser on our fleet, through the exit country you choose. No browser to launch, connect or close.

| Function | Returns | For |
| --- | --- | --- |
| [`screenshot`](https://cdpfleet.com/docs/functions/screenshot) | `image/png` or `image/jpeg` | A PNG or JPEG of the page as a real browser renders it, the viewport or the full page. |
| [`pdf`](https://cdpfleet.com/docs/functions/pdf) | `application/pdf` | The full page as a single-page PDF, A4 or Letter wide. |
| [`markdown`](https://cdpfleet.com/docs/functions/markdown) | `text/markdown; charset=utf-8` | The page's main content as clean Markdown, ready for an LLM or a search index. |
| [`scrape`](https://cdpfleet.com/docs/functions/scrape) | `application/json` | The page in the formats you ask for — HTML, Markdown, text, links, a screenshot, its XHR/fetch calls, cookies, console — after optional clicks and typing, with CSS selectors extracted to JSON. |
| [`map`](https://cdpfleet.com/docs/functions/map) | `application/json` | A site's URLs from its sitemaps and the start page's links, without loading every page — the quick first look before a crawl. |
| [`geo`](https://cdpfleet.com/docs/functions/geo) | `application/json` | The same page from 2–5 countries at once, side by side, with a diff of what changes between them. |
| [`livetab`](https://cdpfleet.com/docs/functions/livetab) | `application/json` | One remote browser tab you — or anyone you send the link to — can see and control in a web browser: log in by hand, solve your own CAPTCHA, show a page from another country, then let your code carry on. |
| [`rawpage`](https://cdpfleet.com/docs/functions/rawpage) | `application/json` | Scrape's first name, kept working: the rendered HTML with the final URL and status, redirects, and optionally the page's XHR/fetch calls with their responses, cookies and console output. |

**Longer work:** [jobs](https://cdpfleet.com/docs/jobs) scrape any number of URLs, crawl or map a whole site, [watch a page live](https://cdpfleet.com/docs/jobs#watch) or [warm up a browser](https://cdpfleet.com/docs/jobs#warmup) in the background, as long as it takes; [monitors](https://cdpfleet.com/docs/monitors) check a page on a schedule and send you a diff when it changes (paid plans).

No key yet? Screenshot, PDF, Markdown and raw page have a free web form at [/functions](https://cdpfleet.com/functions) — a few runs a day, no sign-up.

## Call one

`POST https://cdpfleet.com/v1/functions/<function>` with your API key in `x-api-key` and a JSON body. Every function takes:

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `url` | string | required | The page to load. A public `http` or `https` address: private, loopback, link-local, CGNAT and cloud-metadata addresses, `localhost`, `.local`/`.internal` names and names that resolve to them are refused (`400 invalid_url`). |
| `country` | string | `"random"` | Two-letter country for the exit IP and for the page's locale, timezone, geolocation and `Accept-Language` (see [countries](#countries)); `"random"` picks one. Unknown codes: `400 invalid_country`. |
| `max_wait` | number | `20` | Seconds to wait for the page to load, 1–60 (`400 invalid_option` otherwise). The whole call returns within about `max_wait` + 5 s, so a client timeout of `max_wait` + 10 s is safe. A page that is still loading then comes back partial (below); one that never started: `408 page_timeout`. |
| `proxy` | string or string\[\] | the Community proxy | Omit it to use the free Community proxy in `country`. Or: your own proxy URL (`http://`, `https://`, `socks5://`), a list (one is picked per call), a `cdpfleet-plan…` token, or a residential `cdpfleet-resi…` token (tier, country, device OS, sticky session) billed per GB to your residential balance ([proxies](https://cdpfleet.com/docs/proxies)). `proxy_rules` isn't supported yet (`400 invalid_option`). |

```sh
curl -s https://cdpfleet.com/v1/functions/screenshot -H "x-api-key: $CDPFLEET_API_KEY" \
  -H "content-type: application/json" -d '{"url":"https://example.com/","country":"jp"}' -o shot.png
```

## How it runs, and what it costs

-   **A real browser, a private tab:** each call opens a fresh tab in a warm Camoufox browser (based on Firefox source; not affiliated with Mozilla), with its own proxy, locale, timezone and geolocation for `country`, and closes it at the end. Nothing is shared between calls.
-   **Billed like a browser session:** a call holds one of your plan's [threads](https://cdpfleet.com/docs/sessions) from start to finish and uses browser-minutes per second while it runs. On the free [Community plan](https://cdpfleet.com/community) that's 2 calls at once and 60 minutes per thread a day; paid plans have more ([Community vs paid](https://cdpfleet.com/upgrade)). Calls appear in your [session history](https://cdpfleet.com/docs/dashboard) as `function:<name>`.
-   **Proxy traffic:** the Community proxy and your own proxies cost nothing extra; a `cdpfleet-resi…` token is billed per GB to your [residential balance](https://cdpfleet.com/residential-proxy), like in a browser session.
-   **Retries for you:** if the browser crashes mid-call, the call runs once more on another browser; you get one result or one error.
-   **Partial pages instead of nothing:** the call waits for the document, then for the page's `load` within `max_wait`. Pages heavy with ads and trackers often never finish loading; then you get `200` with what had loaded (the current viewport, its PDF or Markdown, or the HTML and requests so far, with `"partial": true` in a raw page) and the header `x-cdpfleet-partial: load_timeout`. Raise `max_wait` for more.
-   **Country health:** each country's Community proxy is checked every 2 minutes. `"random"` only picks countries that answer quickly; a country you pick that is down gets `503 country_unavailable` at once, and a slow one still runs with `x-cdpfleet-warning: country proxy slow`.
-   **Up to 60 seconds:** calls are synchronous. Long-running functions (crawls) will come with a submit-then-poll API.

## Your own browser (paid plans)

Add `browser` and the call runs in a browser you choose instead of a pooled Camoufox tab: launched with your API key as one of your sessions, held on your threads and billed per second like any session (headful takes 2 threads; `memory` multiplies). The function runs in one context and the session closes at the end.

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `browser` | string | none (pooled tab) | Any browser: `chrome`, `edge`, `brave`, `opera`, `whale`, `yandex`, `chromium`, `patchright`, `rebrowser`, `camoufox`, `firefox`, `webkit`. |
| `launch` | object | `{}` | The same JSON a [launch](https://cdpfleet.com/docs/browsers) takes: `channel`, `version`, `headless`, `proxy`, `proxy_rules`, `memory`, Camoufox options and so on. Without `proxy`, the Community proxy in `country`. |
| `device` | string | none | A Playwright device name, e.g. `"iPhone 15"`, `"Pixel 7"`, `"Galaxy S24"`, `"iPad Pro 11"`. Unknown names: `400 invalid_option`. |
| `context` | object | `{}` | Overrides after `device`: `viewport {width, height}`, `user_agent`, `locale`, `timezone`, `is_mobile`, `has_touch`, `device_scale_factor`. |

-   **Text PDFs:** on Chrome, Edge, Brave, Opera, Whale, Yandex, Chromium, Patchright and Rebrowser, `pdf` returns a native PDF with selectable text.
-   **Mobile:** a `device` sets the viewport, user agent, scale factor, touch and mobile mode (for example `"iPhone 15"` on WebKit gave a 1179×1977 screenshot). Firefox and Camoufox have no mobile mode; the rest is applied and `x-cdpfleet-warning` says so.
-   **Launch errors are your session's:** a bad launch option, no free threads or an empty balance come back exactly as from a launch (`400 invalid_*`, `429` with `Retry-After`, …). On Community: `403 own_browser_not_available`.

```sh
curl -s https://cdpfleet.com/v1/functions/pdf -H "x-api-key: $CDPFLEET_API_KEY" -H "content-type: application/json"   -d '{"url":"https://example.com/","browser":"chrome","launch":{"headless":"new","channel":"beta"},"format":"Letter"}' -o page.pdf
```

## Errors

Errors are JSON `{"error": "…", "message": "…"}`. Every response after a call has started carries `x-call-id` — quote it to support; it matches the call in your session history.

| Status | `error` | When |
| --- | --- | --- |
| 400 | `url_required` / `invalid_url` | No `url`, or not a public http(s) address. Nothing is billed. |
| 400 | `invalid_country` | Not a supported country code; the message lists them. |
| 400 | `invalid_option` | A field out of range or of the wrong type; the message names it. |
| 400 | `invalid_proxy` | `proxy` isn't a URL, a list of URLs or a valid token. |
| 400 | `unknown_function` | Not one of `screenshot`, `pdf`, `markdown`, `scrape`, `map`, `geo`, `livetab`, `rawpage`. |
| 401 | `missing_api_key` / `invalid_api_key` | No key, or an unknown or revoked one. |
| 402 | `proxy_balance_exhausted` | A `cdpfleet-resi` proxy and an empty residential balance; top up in the dashboard. |
| 403 | `no_plan` / `account_inactive` | The account has no active plan, or is suspended. |
| 408 | `page_timeout` | Not even the document arrived within `max_wait` (a page that started loading comes back partial instead). |
| 429 | `threads_exceeded`, `daily_quota_exhausted`, `hourly_quota_exhausted` | Your threads are all in use or the minutes are used up; wait `Retry-After` seconds. |
| 503 | `country_unavailable` | The Community proxy for the `country` you picked is down right now; pick another or `"random"`, or wait `Retry-After` (120 s). |
| 503 | `navigation_failed` | The page couldn't be reached through the proxy (connection reset or refused) even after a retry; the message has the browser's reason. |
| 5xx | e.g. `launch_failed`, `internal_error` | Our side failed; retry after `Retry-After`. |

## Countries

`ae` `ar` `at` `au` `be` `br` `ca` `ch` `cl` `cn` `co` `cz` `de` `dk` `eg` `es` `fi` `fr` `gb` `gr` `hk` `hu` `id` `ie` `il` `in` `it` `jp` `kr` `mx` `my` `ng` `nl` `no` `nz` `ph` `pl` `pt` `ro` `ru` `sa` `se` `sg` `th` `tr` `tw` `ua` `uk` `us` `vn` `za` — `uk` is the same as `gb`.

---
Source: https://cdpfleet.com/docs/functions · Markdown: https://cdpfleet.com/docs/functions.md · All docs for AI tools: https://cdpfleet.com/llms.txt
