# S3 storage

> A dedicated bucket with credentials scoped to it, in one command.

```bash
npx extraorbital add s3
```

```txt
✓ Provisioned s3/default (bucket cosmic-otter-default, us-east-1)
✓ Wrote 5 variables to .env

  S3_BUCKET, S3_ENDPOINT, S3_REGION, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY
```

A project that mentions any `S3_*` variable gets this from
[`extraorbital provision`](/docs/quickstart#how-autopilot-decides) without naming it.

## What it writes

| Variable | Example |
| --- | --- |
| `S3_BUCKET` | `cosmic-otter-default` |
| `S3_ENDPOINT` | `https://s3.extraorbital.dev` |
| `S3_REGION` | `us-east-1` |
| `S3_ACCESS_KEY_ID` | `SOAK7F2A91C4E8B3D6` |
| `S3_SECRET_ACCESS_KEY` | `wJalrXUtnFEMI/…` |

The bucket is named `{project}-{slug}` and the keys are scoped to it alone, so an
agent can never read another project's objects.

## Options

```bash
npx extraorbital add s3 [--slug <name>] [--public] [--region <region>]
```

| Flag | Default | Description |
| --- | --- | --- |
| `--slug` | `default` | A second, fully separate bucket in the same project |
| `--public` | off | Objects are publicly readable at `{endpoint}/{bucket}/{key}` |
| `--region` | `us-east-1` | One of `us-east-1`, `eu-central-1`, `ap-southeast-1` |

Options apply at creation. Re-running `add` with different options returns the
existing bucket unchanged — remove it first if you need a different configuration.

## Prototype allowance

**1 GB stored, 10K simple and 2K advanced operations per month, and 10 GB of
transfer** on the Prototype plan, counted across your whole account. There is no
limit on how many buckets you hold, because a bucket costs nothing until it
holds something. Past the allowance, $0.023/GB-mo stored, $0.09/GB out, $0.0004
per 1,000 simple operations and $0.005 per 1,000 advanced ones — our own cost,
with nothing added — on [a paid plan](/pricing).

## Use it

Any S3 client works:

```ts title="storage.ts"
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({
  endpoint: process.env.S3_ENDPOINT,
  region: process.env.S3_REGION,
  credentials: {
    accessKeyId: process.env.S3_ACCESS_KEY_ID!,
    secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,
  },
});

await s3.send(
  new PutObjectCommand({ Bucket: process.env.S3_BUCKET, Key: "report.json", Body: data }),
);
```

## Next

- [Quickstart](/docs/quickstart) — slugs, idempotency and sharing
- [Pricing](/pricing) — plans, allowances and rates

---

More for agents: [Docs index](https://extraorbital.dev/sitemap.md) · [llms.txt](https://extraorbital.dev/llms.txt) · [agents.md](https://extraorbital.dev/agents.md)
