> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blobrouter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API

> HTTP reference with curl examples for router, scanner, providers, keys, and billing endpoints.

<Info>
  **BlobRouter v0.1** · Last updated: August 2026 · Architecture version: **2.0**
</Info>

Base URL: `https://api.blobrouter.com`

Two auth styles:

* **API key** — `Authorization: Bearer br_live_…` (SDK / router)
* **Dashboard JWT** — `Authorization: Bearer <supabase_access_token>` (scanner, providers, analytics, billing, key rotate)

All JSON errors look like:

```json theme={null}
{ "error": "Human readable message", "code": "error_code" }
```

Responses include `X-Request-ID`. Rate limit exceeded returns `429` with `Retry-After: 60`.

***

## Health

```bash theme={null}
curl https://api.blobrouter.com/health
```

***

## Router (API key)

### Who am I

```bash theme={null}
curl https://api.blobrouter.com/v1/me \
  -H "Authorization: Bearer $BLOBROUTER_API_KEY"
```

### Init upload

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/upload/init \
  -H "Authorization: Bearer $BLOBROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "example.jpg",
    "contentType": "image/jpeg",
    "fileSizeBytes": 12345,
    "priority": "hot"
  }'
```

Returns `fileId`, `presignedUrl`, `provider`, `savedVsAws`, optional `routingWarning`.

### Complete upload

After you `PUT` the file to `presignedUrl`:

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/upload/complete \
  -H "Authorization: Bearer $BLOBROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"fileId":"FILE_UUID"}'
```

### Get download URL

```bash theme={null}
curl https://api.blobrouter.com/v1/file/FILE_UUID \
  -H "Authorization: Bearer $BLOBROUTER_API_KEY"
```

### Delete file

```bash theme={null}
curl -X DELETE https://api.blobrouter.com/v1/file/FILE_UUID \
  -H "Authorization: Bearer $BLOBROUTER_API_KEY"
```

***

## Scanner (dashboard JWT)

### Connect AWS

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/scanner/connect \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "roleArn": "arn:aws:iam::123456789012:role/BlobRouterScanner",
    "externalId": "YOUR_EXTERNAL_ID",
    "regions": ["us-east-1"]
  }'
```

### Start scan

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/scanner/scan \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{"connectionId":"CONNECTION_UUID"}'
```

### Scan results

```bash theme={null}
curl https://api.blobrouter.com/v1/scanner/results/SCAN_UUID \
  -H "Authorization: Bearer $DASHBOARD_JWT"
```

### Scan history

```bash theme={null}
curl https://api.blobrouter.com/v1/scanner/history \
  -H "Authorization: Bearer $DASHBOARD_JWT"
```

### Approve recommendation

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/scanner/recommendations/REC_UUID/approve \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{"targetProvider":"backblaze-b2"}'
```

### Migration status

```bash theme={null}
curl https://api.blobrouter.com/v1/scanner/migration/MIGRATION_UUID \
  -H "Authorization: Bearer $DASHBOARD_JWT"
```

***

## Providers (dashboard JWT)

### Save provider credentials

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/providers \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "cloudflare-r2",
    "accessKeyId": "...",
    "secretAccessKey": "...",
    "bucketName": "my-bucket",
    "region": "auto",
    "accountId": "CLOUDFLARE_ACCOUNT_ID"
  }'
```

### Test provider

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/providers/test \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{"provider":"cloudflare-r2"}'
```

### Get API key

```bash theme={null}
curl https://api.blobrouter.com/v1/providers/api-key \
  -H "Authorization: Bearer $DASHBOARD_JWT"
```

### Regenerate API key

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/providers/api-key/regenerate \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{}'
```

***

## API key rotation (dashboard JWT)

Preferred rotation endpoint:

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/keys/rotate \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{}'
```

Returns `{ "newApiKey": "br_live_…", "rotatedAt": "…" }`. The previous key stops working immediately.

***

## Analytics (dashboard JWT)

```bash theme={null}
curl https://api.blobrouter.com/v1/analytics/summary \
  -H "Authorization: Bearer $DASHBOARD_JWT"

curl https://api.blobrouter.com/v1/analytics/monthly \
  -H "Authorization: Bearer $DASHBOARD_JWT"

curl "https://api.blobrouter.com/v1/analytics/routing-history?limit=10&offset=0" \
  -H "Authorization: Bearer $DASHBOARD_JWT"
```

***

## Billing (dashboard JWT)

```bash theme={null}
curl -X POST https://api.blobrouter.com/v1/billing/checkout \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{"plan":"starter"}'

curl -X POST https://api.blobrouter.com/v1/billing/portal \
  -H "Authorization: Bearer $DASHBOARD_JWT" \
  -H "Content-Type: application/json" \
  -d '{}'
```

## Related

* [Authentication](/api/authentication)
* [Errors](/api/errors)
* [Rate limits](/api/rate-limits)
* [Retries](/api/retries)
* [Request IDs](/api/request-ids)
* [Pagination](/api/pagination)
* [Idempotency](/api/idempotency)
