Router9
Documentation
API Reference

Storage

Persistent file storage for AI agents

Overview

Each agent plan has dedicated S3-compatible file storage. Files are isolated per agent — no agent can access another agent's files.

Upload a File

POST /v1/storage/upload

Request

curl https://api.router9.com/v1/storage/upload \
  -H "Authorization: Bearer sk-r9k-your-key" \
  -F [email protected]

Send the file as multipart/form-data with the field name file.

Response

// 201 Created
{
  "data": {
    "id": "file-abc123",
    "filename": "document.pdf",
    "contentType": "application/pdf",
    "sizeBytes": 102400,
    "createdAt": "2026-04-06T10:00:00Z"
  }
}

Limits

  • Maximum file size: 50 MB per file
  • Total storage depends on your plan (see below)

Errors

// 400 - No file provided
{ "message": "No file provided. Send as multipart form data with field 'file'." }

// 413 - File too large
{ "message": "File exceeds maximum size of 50MB." }

// 413 - Quota exceeded
{ "message": "Storage quota exceeded. Used 4.5 GB of 5.0 GB. File size: 600 MB." }

List Files

GET /v1/storage/files

Query Parameters

ParameterTypeDefaultDescription
pagenumber1Page number (min: 1)
limitnumber50Items per page (max: 100)

Response

{
  "data": [
    {
      "id": "file-abc123",
      "filename": "document.pdf",
      "contentType": "application/pdf",
      "sizeBytes": 102400,
      "createdAt": "2026-04-06T10:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "total": 12
  }
}

Download a File

GET /v1/storage/files/:id

Returns a 302 redirect to a presigned download URL (valid for 1 hour).

curl -L https://api.router9.com/v1/storage/files/file-abc123 \
  -H "Authorization: Bearer sk-r9k-your-key" \
  --output document.pdf

Upload via Presigned URL

POST /v1/storage/presigned-upload

Returns a presigned PUT URL for direct client-to-S3 upload. The file metadata record is created immediately.

Request

curl https://api.router9.com/v1/storage/presigned-upload \
  -H "Authorization: Bearer sk-r9k-your-key" \
  -H "Content-Type: application/json" \
  -d '{"filename": "report.pdf", "contentType": "application/pdf", "sizeBytes": 102400}'

Response

// 200 OK
{
  "data": {
    "id": "file-abc123",
    "filename": "report.pdf",
    "contentType": "application/pdf",
    "sizeBytes": 102400,
    "createdAt": "2026-04-06T10:00:00Z",
    "uploadUrl": "https://s3.../presigned-put-url",
    "expiresIn": 3600
  }
}

Then upload the file directly to S3:

curl -X PUT "https://s3.../presigned-put-url" \
  -H "Content-Type: application/pdf" \
  --data-binary @report.pdf

Get Download URL

GET /v1/storage/files/:id/url

Returns a presigned download URL as JSON (alternative to the 302 redirect endpoint).

curl https://api.router9.com/v1/storage/files/file-abc123/url \
  -H "Authorization: Bearer sk-r9k-your-key"

Response

{
  "data": {
    "url": "https://s3.../presigned-get-url",
    "filename": "report.pdf",
    "contentType": "application/pdf",
    "expiresIn": 3600
  }
}

Delete a File

DELETE /v1/storage/files/:id

Response

{
  "message": "File deleted."
}

Deletion is permanent and cannot be undone.

Check Storage Quota

GET /v1/storage/quota

Response

{
  "data": {
    "usedBytes": 1073741824,
    "limitBytes": 5368709120,
    "usedFormatted": "1.0 GB",
    "limitFormatted": "5.0 GB"
  }
}

Storage Limits by Plan

PlanStorageOperations/Period
Free100 MB100
Assistant5 GB500
Engineer10 GB5,000

On this page