# Bring your own key

rent.dev's own sandboxes run on the prepaid balance. Everything else runs on a key you bring: the vendor bills you directly, and rent.dev places the work and reports on it through the same API.

`POST https://api.rent.dev/v1/byok/credentials`

## What needs your own key

| Compute | Whose key | Who bills |
| --- | --- | --- |
| rent.dev sandboxes | None: a rent.dev API key is enough. | rent.dev, from the balance. |
| GPU pods | Your RunPod key. | RunPod. |
| Sandboxes at E2B Cloud | Your E2B key. | E2B. |
| Sandboxes at Vercel | Your Vercel token. | Vercel. |

A GPU pod never touches the rent.dev balance, and no hold is taken for one. rent.dev sells no GPU time of its own.

## Store a credential

```sh
curl -sX POST https://api.rent.dev/v1/byok/credentials -H "Authorization: Bearer $RENT_KEY" -H "Content-Type: application/json" \
  -d '{"vendor":"runpod","fields":{"api_key":"…"}}'
```

| Vendor | Fields |
| --- | --- |
| `e2b` | `api_key` |
| `vercel` | `token`, `team_id`, `project_id` |
| `runpod` | `api_key` |

The credential is checked with one read-only call to the vendor, then stored encrypted. It is never returned: a list shows ids, vendors, labels and times only.

- `GET /v1/byok/credentials`: what is stored.
- `DELETE /v1/byok/credentials/{id}`: removes one. It answers 200 with `orphaned`: every sandbox and GPU pod started with the key that is still running. Each keeps running and its vendor keeps billing you. rent.dev can no longer stop it, so terminate it at the vendor by its `vendor_resource_id`.
- Over MCP: `rent_set_byok_credential`.

## GPU pods

`POST https://api.rent.dev/v1/gpu-pods`

```sh
curl -sX POST https://api.rent.dev/v1/gpu-pods -H "Authorization: Bearer $RENT_KEY" -H "Content-Type: application/json" \
  -d '{"gpu_type":"NVIDIA GeForce RTX 4090","image":"runpod/pytorch:2.4.0-py3.11-cuda12.4.1-devel-ubuntu22.04"}'
```

| Body field | Type | Description |
| --- | --- | --- |
| `gpu_type` | `string` | Required. RunPod GPU type id, as listed by its catalog. |
| `gpu_count` | `integer, at least 1` | Default 1. |
| `image` | `string` | Required. |
| `cloud_type` | `SECURE \| COMMUNITY` | Default SECURE. |
| `container_disk_gb` | `integer, at least 1` | Default 20. |
| `volume_gb` | `integer, at least 0` | Default 0. |
| `ports` | `array of string` |  |
| `env` | `map of string to string` |  |
| `credential_id` | `string` | RunPod credential to use; default the account's only RunPod credential. |

RunPod bills the pod by the hour from the moment it starts until you terminate it. `exec` passes RunPod's own limits through: a timeout of 1 to 25 seconds and at most 1 MiB of output.

- `GET /v1/gpu-pods` and `GET /v1/gpu-pods/{id}`
- `POST /v1/gpu-pods/{id}/exec`
- `GET /v1/gpu-pods/{id}/logs`: server-sent events.
- `DELETE /v1/gpu-pods/{id}`: ends the pod and RunPod's billing for it.

Hourly rates by GPU type are on [the price board](/prices#gpu).

## Sandboxes on your own vendor key

> Running a sandbox on your own E2B key or Vercel token has been tested against stand-ins for E2B's and Vercel's APIs, and has not yet been run against a live account at either vendor.

A sandbox is placed on rent.dev's own supply while that can take it. To run one on your own vendor key, hold a [stored credential](#store) for the vendor, name its endpoint in `routing.allow`, and name rent.dev's own endpoint in `routing.deny`:

```sh
curl -sX POST https://api.rent.dev/v1/sandboxes -H "Authorization: Bearer $RENT_KEY" -H "Content-Type: application/json" \
  -d "{\"routing\":{\"allow\":[\"byok-e2b\"],\"deny\":[\"$OWN_ENDPOINT_ID\"]}}"
```

`$OWN_ENDPOINT_ID` is the `id` of the endpoint whose `supplier` is `own` in `GET /v1/status`, which lists every endpoint id. When there are several, name each one.

`allow` alone does not move a sandbox to your key. It adds the endpoint to those a create may use, and the cheapest that can take the sandbox wins, with rent.dev's own supply ahead on a tie. At list rates rent.dev's own supply is never dearer, so with `allow` alone a sandbox lands on your key only while own supply is down or full.

An id in `routing.allow` that names no endpoint answers 400 `invalid_request`, and the answer lists the ids that exist. An endpoint you allow without a stored credential for its vendor is not used: with rent.dev's own endpoint denied too, the create answers 503 `no_capacity`.

From the E2B SDK, set the metadata key `rent.dev/allow` to the same ids; see [E2B compatibility](/docs/e2b#metadata). That path has no `deny`, so it reaches your key only while own supply is down or full. The sandbox's `billed_by` says who bills it.

> With rent.dev's own supply down or full, a create still places on an endpoint you have allowed. Without one it answers 503 `no_capacity`.

## What each vendor can do

The native API is the same wherever a sandbox runs. A call the vendor has no equivalent for answers 400 `unsupported_parameter`. The E2B and Vercel columns have been tested against stand-ins for those vendors' APIs, and have not yet been run against a live account at either vendor.

| Call | Sandbox at E2B | Sandbox at Vercel | GPU pod at RunPod |
| --- | --- | --- | --- |
| Create | Yes | Yes | Yes |
| Connect | Yes, from the E2B SDK | No | No |
| Pause | Yes | No | No |
| Resume | Yes | No | No |
| Snapshot | No. Snapshot it with E2B's own API | No | No |
| Fork | Yes, from the E2B SDK | No | No |
| Extend the timeout | Yes | Yes, to a later time only | No |
| Run commands | Yes | Yes | Yes |
| Read and write files | Yes | Yes, without listing a directory | No |
| Stream logs | Yes | No | Yes |

A sandbox at Vercel cannot be paused, resumed, snapshotted or forked through rent.dev. It has no log stream either: a command's output comes back from `exec`.

Connect, snapshot and fork are calls of the E2B SDK, served on [the E2B paths](/docs/e2b). Those paths reach a sandbox that runs on E2B's API: rent.dev's own, or one on your E2B key. A snapshot is taken of rent.dev's own sandboxes only.

A GPU pod has its own calls, listed under [GPU pods](#gpu). It has no timeout, and no call pauses or resumes one: a pod runs, and RunPod bills it, until you terminate it.

## Usage and showback

`GET /v1/usage` puts both kinds of usage in one report: `own`, what rent.dev charged for its own sandboxes, and `byok`, an estimate of what each vendor will bill you. A `byok` line's `source` is `vendor_billing` when it comes from the vendor's billing API and `estimate` when it is worked out from start and stop times.

rent.dev adds no fee to usage a vendor bills. The report states the rate as `byok_fee_bps`.
