OutputLayer turns artifact storage for AI agents into a single API call.
Built for AI agents that generate files, reports, images, datasets, and other artifacts.
OutputLayer gives those artifacts a place to live.
OutputLayer is a REST API that stores AI-generated artifacts, serves them via CDN or authenticated stream, and expires them automatically.
Every response — including errors — includes an agent_contract field that tells the agent exactly what it can safely do next.
OutputLayer acts as a storage layer for artifacts generated by agents and automated systems.
Web page: outputlayer.dev
Live API: api.outputlayer.dev
Playground: outputlayer.dev/playground
When an AI agent generates a file, the developer typically reaches for one of three approaches:
Base64 in tool responses. Works for small payloads, but destroys context windows at scale, produces no sharable URL, and disappears when the conversation ends.
Temporary files. Convenient locally, but ephemeral — lost on process restart, invisible to other agents, and unreachable over the network.
S3 directly. Reliable, but requires an AWS account, IAM credentials, a bucket, a bucket policy, a presigned URL implementation, and a custom expiration strategy. Half a day of infrastructure work before an agent can reliably save and share artifacts.
None of these options were designed for agents. They don't provide machine-readable retry guidance, don't require idempotency, and don't expire automatically. They were built for applications, not autonomous systems.
A single REST API where agents can:
- Upload artifacts as JSON (base64-encoded) or multipart form-data
- Retrieve metadata by ID, including status and lifecycle state
- Stream private artifact content via authenticated endpoint
- Share public artifacts via Cloudflare CDN
- Let files expire automatically — no cleanup required
Every response includes agent_contract: a structured field with next_actions, retryable, content_accessible, safe_to_share, and expires_in_seconds. Agents don't parse error messages — they read agent_contract.
OutputLayer underwent a local capacity validation phase before public launch. Eight load test scenarios were executed using Grafana k6 to verify correctness, throughput, and resource stability.
| Metric | Result |
|---|---|
| Single-account throughput | ~1,156 req/s (p95: 33 ms) |
| Multi-account throughput | ~1,293 req/s (p95: 71 ms) |
| Error rate (all scenarios) | 0% |
| Idempotency correctness | Verified under 10-way concurrency, 0 duplicates |
| Soak test (30 min) | Stable memory, no leaks, no pool exhaustion |
| Optimal PG pool size | 20 connections |
These numbers represent server-side processing capacity with local filesystem storage. Production latency depends on object storage (Cloudflare R2) and network round-trips.
See: docs/CAPACITY_VALIDATION_SUMMARY.md
OutputLayer maintains data correctness through transactional billing validation (FOR UPDATE on account rows), idempotency enforcement on all write operations, and storage accounting verification. Concurrent load tests confirmed zero duplicate artifacts, zero storage accounting drift, and deterministic idempotency behavior across all scenarios.
Validation focused on concurrency correctness, throughput ceilings, memory stability, and connection pool behavior under sustained load. Object storage latency (Cloudflare R2) is validated separately during staging tests against production infrastructure.
1. Register an API key
No account, no email. One request.
curl -X POST https://api.outputlayer.dev/v1/keys/register \
-H "Content-Type: application/json" \
-d '{}'Response:
{
"apiKey": "ol_live_a3f9...",
"accountId": "key_01JXZK..."
}The key is returned once. Copy it.
2. Upload an artifact
Idempotency-Key is required on every write. Use a unique value per upload.
curl -X POST https://api.outputlayer.dev/v1/outputs \
-H "Authorization: Bearer ol_live_a3f9..." \
-H "Idempotency-Key: my-job-001" \
-H "Content-Type: application/json" \
-d '{
"mimeType": "application/json",
"label": "report.json",
"content": "eyJoZWxsbyI6IndvcmxkIn0="
}'content must be base64-encoded. For binary files, use multipart/form-data with the file part named content.
3. Retrieve metadata
curl https://api.outputlayer.dev/v1/outputs/out_01JXZK... \
-H "Authorization: Bearer ol_live_a3f9..."A successful upload returns:
{
"outputId": "out_01JXZK4XKRWABCDE",
"status": "ready",
"mimeType": "application/json",
"label": "report.json",
"sizeBytes": 18,
"contentUrl": "https://api.outputlayer.dev/v1/outputs/out_01JXZK4XKRWABCDE/content",
"publicUrl": null,
"expiresAt": "2026-03-18T14:22:00.000Z",
"createdAt": "2026-03-11T14:22:00.000Z",
"agent_contract": {
"version": "1",
"content_accessible": true,
"safe_to_share": false,
"retryable": false,
"expires_in_seconds": 604800,
"next_actions": [
{
"action": "download_content",
"available": true,
"recommended": true,
"description": "Download the raw content via the authenticated content endpoint.",
"method": "GET",
"endpoint": "/v1/outputs/out_01JXZK4XKRWABCDE/content"
},
{
"action": "delete_output",
"available": true,
"recommended": false,
"description": "Delete this output when it is no longer needed.",
"method": "DELETE",
"endpoint": "/v1/outputs/out_01JXZK4XKRWABCDE"
}
]
}
}agent_contract is present on every response — successful uploads, metadata retrieval, errors, and terminal states. The contract tells the agent what it can safely do next without any additional prompt engineering.
For a quota_exhausted error, next_actions contains buy_credits. For rate_limited, it contains retry_after_wait with a retry_after_seconds value. For upload_failed, it contains retry_same_request with retryable: true. The agent never needs to parse an error string.
Every response includes agent_contract — a structured field that answers: "What should the agent do next?"
Fields:
content_accessible— whether the artifact can be downloaded right nowsafe_to_share— whether the public CDN URL can be shared with end usersretryable— whether the same request can safely be retriedexpires_in_seconds— time until the artifact expires, ornullif it doesn'tnext_actions— ordered list of available actions, each withmethod,endpoint,available, andrecommended
V1 fields are stable — additions are non-breaking, removals require a /v2/ route with a minimum 6-month deprecation period.
POST /v1/outputs requires an Idempotency-Key header. Sending the same key with the same payload returns the original response. Sending the same key with a different payload returns 409 idempotency_conflict.
This makes uploads safe to retry in agent pipelines where the agent cannot always determine whether a previous request succeeded.
All artifacts expire. The default TTL is 7 days. A custom expiresAt can be set at upload time. After expiry, the artifact returns 410 output_expired and agent_contract.content_accessible: false.
No cleanup jobs required.
Uploads are private by default, accessible only via the authenticated /v1/outputs/:id/content endpoint.
Set "public": true at upload time to generate a CDN URL (publicUrl). Public artifacts are served directly from Cloudflare CDN. Requests to /v1/outputs/:id/content for public artifacts return a 302 redirect to the CDN URL.
| Endpoint | Purpose |
|---|---|
/AGENTS.md |
Full agent integration guide |
/.well-known/agent.json |
MCP-compatible capability manifest |
/v1/tool |
Machine-readable tool definition |
/v1/schema |
OpenAPI 3.0 JSON schema |
/v1/capabilities |
Current limits, pricing, and quota |
/v1/examples |
Code examples for common operations |
| API Reference (Swagger UI) | api.outputlayer.dev/docs |
| Interactive Playground | outputlayer.dev/playground |
| Agent Integration Guide | api.outputlayer.dev/AGENTS.md |
| OpenAPI Schema | api.outputlayer.dev/v1/schema |
| Capacity Validation Summary | docs/CAPACITY_VALIDATION_SUMMARY.md |
| Testing Methodology | docs/TESTING_METHODOLOGY.md |
| Validation Results Overview | docs/VALIDATION_RESULTS_OVERVIEW.md |
Free tier — no credit card required:
- 5 uploads
- 250 MB storage
If OutputLayer becomes useful for real workloads, additional uploads can be purchased using credits. Current pricing is available at /v1/capabilities.
Every authenticated response includes quota headers:
X-OutputLayer-Free-Remaining: 4
X-OutputLayer-Credits-Remaining: 0
X-OutputLayer-Storage-Used-Bytes: 18
X-OutputLayer-Storage-Limit-Bytes: 262144000
OutputLayer is an early-stage developer tool. The V1 API contract is stable. The agent_contract field schema is versioned — breaking changes will be introduced only via a /v2/ route with a minimum 6-month deprecation period.
Stack:
- Node.js + TypeScript (Express)
- PostgreSQL
- Cloudflare R2 (object storage)
- Cloudflare CDN (
cdn.outputlayer.dev) - Railway (hosting)
Free tier artifacts are best-effort.
OutputLayer is maintained by an independent developer and is currently in active early-stage development.
MIT