# Direct and proxy

## Direct

The reader's browser calls your API itself, with what the form holds and nothing else:

- no cookies: the request is sent with `credentials: 'omit'`;
- no referrer: `referrerPolicy: 'no-referrer'`;
- no redirects: a redirect shows as "The API answered with a redirect, which the playground doesn’t follow.";
- only to the servers your document lists that pass the page's `connect-src` checks: see [Caching and security](../api-reference/caching-and-security).

Your API has to answer CORS for this to work: see [CORS for Try it](cors). The credentials a reader types stay in their browser.

## Through the proxy

The API client’s proxy (Pro) calls only hosts you verified, follows no redirects and stores nothing.

An owner or admin turns it on for the project, and adds and [verifies](verified-hosts) each host. Try it then offers it beside direct mode. The browser sends the request as a JSON envelope to `/r/<workspace>/<project>/proxy`, and our server makes one request, built from that envelope only:

- `https` only, on the default port, with no user name in the URL, to a public host verified for this project;
- `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD` and `OPTIONS`;
- a body of up to 256 KB;
- no cookies, no `Origin` or `Referer`, and none of the `Host`, `Forwarded`, `X-Forwarded-*`, `CF-*`, `Sec-*` or `Proxy-*` headers;
- its own `User-Agent`, which names the Latitude 10 playground;
- sent once, never retried, and never redirected;
- cut off after 15 seconds, and its answer read up to 1 MB.

The answer comes back as JSON: the status, the headers without `Set-Cookie`, the body as text or base64, whether it was cut, and the time it took. Nothing the API sends becomes a page on our origin.

The proxy serves the hosted reference at `/r/` and its embed. The reference inside a docs site sends directly.

The proxy's calls count per project a day and per reader's IP a minute: see [Plans and limits](../get-started/plans-and-limits#api-client).

## The proxy's errors

| Status | The `error` |
| --- | --- |
| `400` | What's wrong with the envelope, such as `Send an https URL.` or `That method isn’t allowed.` |
| `403` | `This host isn’t verified for this API’s proxy.` |
| `413` | `The body is over 256 KB.` |
| `429` | `Too many requests through the proxy. Wait a minute.` or `This API’s proxy has reached today’s limit. Send directly from your browser, or try tomorrow.` |
| `502` | `The API couldn’t be reached.` |
| `504` | `The API didn’t answer within 15 seconds.` |

## Where this comes from

- `app/reference/_lib/playground/client.ts`
- `app/reference/_lib/playground/proxy.ts`
- `app/reference/_lib/playground/csp.ts`
- `app/r/_lib/proxy.ts`
- `app/r/[ws]/[project]/proxy/route.ts`
