Indie project integration

Ship file uploads without building storage infrastructure.

Keep your app's users and business data where they are. Files CDN gives your backend scoped access to buckets, objects, signed URLs, and provider storage.

01

Quickstart

  1. Create a projectSign up, then open your default project.
  2. Attach storageAdd S3, R2, GCS, Azure Blob, or Vercel Blob and attach a bucket.
  3. Create a keyUse API Access and scope it to the smallest bucket and permissions.
FILES_CDN_URL=https://cdn.hevo.dev
FILES_CDN_API_KEY=replace-with-your-key
FILES_CDN_PROJECT_ID=replace-with-your-project-id
FILES_CDN_BUCKET_ID=replace-with-your-bucket-id

Keep these values in server-only environment variables. Never expose an API key in browser JavaScript, mobile bundles, or public environment variables.

02

Use a scoped API key

Grant files:read for listing and downloads, files:write for uploads and mutations, and buckets:read only for discovery. A bucket-scoped key is the safest default for a small app.

curl \
  -H "x-api-key: $FILES_CDN_API_KEY" \
  "https://cdn.hevo.dev/api/v1/projects/$FILES_CDN_PROJECT_ID/buckets/$FILES_CDN_BUCKET_ID/objects?prefix=avatars/"

03

Upload and download objects

Small files can use the proxy API. For larger files, request a short-lived signed upload contract so the file goes directly to your provider.

curl -X PUT \
  -H "x-api-key: $FILES_CDN_API_KEY" \
  -H "content-type: image/png" \
  --data-binary @avatar.png \
  "https://cdn.hevo.dev/api/v1/projects/$FILES_CDN_PROJECT_ID/buckets/$FILES_CDN_BUCKET_ID/objects/avatars/user-123.png"
curl -X POST \
  -H "x-api-key: $FILES_CDN_API_KEY" \
  -H "content-type: application/json" \
  -d '{"key":"videos/demo.mp4","contentType":"video/mp4"}' \
  "https://cdn.hevo.dev/api/v1/projects/$FILES_CDN_PROJECT_ID/buckets/$FILES_CDN_BUCKET_ID/upload-url"

The upload response contains a normalized key and provider contract. Use the returned contract immediately, then discard it. Private previews and downloads use the download URL endpoint.

04

Use OAuth for workers

For cron jobs and background workers, create a confidential OAuth client in API Access. Exchange its one-time secret using client credentials and send the resulting access token as a bearer token.

curl -X POST "https://cdn.hevo.dev/api/auth/oauth2/token" \
  -H "content-type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=$FILES_CLIENT_ID" \
  --data-urlencode "client_secret=$FILES_CLIENT_SECRET" \
  --data-urlencode "scope=files:read files:write"
curl \
  -H "authorization: Bearer $FILES_ACCESS_TOKEN" \
  "https://cdn.hevo.dev/api/v1/projects/$FILES_CDN_PROJECT_ID/buckets/$FILES_CDN_BUCKET_ID/objects"

05

Security defaults

  • Keep provider credentials inside Files CDN; they are encrypted at rest.
  • Use bucket-scoped credentials and the smallest permission set.
  • Use signed URLs for browser uploads and private previews; do not proxy large files unnecessarily.
  • Preserve the requestId from API errors when reporting integration failures.