OpenCall

Neon Object Storage

The demo path for attachment storage — no card, and no account you do not already have.

Neon's S3-compatible storage. Pick this one for a demo: it asks for no card, and if you already use Neon for Database it adds no new account.

Not for a real community

Egress counts against the project's 5 GB/month network allowance, shared with the database. When it runs out, Neon suspends the compute until the next cycle — taking your app down with it. For production use Cloudflare R2 instead.

Install the Neon CLI:

npm install -g neonctl

Authenticate with the same API key from Database. If you do not have one, generate it in the Neon Console under Account settings → API keys.

export NEON_API_KEY="PASTE_YOUR_KEY_HERE"

Create the bucket with public read enabled:

neonctl buckets create opencall-uploads --access-level public_read

The name becomes R2_BUCKET. public_read is required: the app builds image URLs directly, with no signature, so anonymous reads have to work.

In the Neon Console, open your branch → Credentials → Create credential, with the storage:read and storage:write scopes.

Both values are shown only once:

  • token_id → R2_ACCESS_KEY_ID
  • s3_secret_access_key → R2_SECRET_ACCESS_KEY

Take the branch's storage endpoint, in the format https://br-<branch-id>.storage.c-1.<region>.aws.neon.tech → R2_ENDPOINT.

Set R2_REGION to the project's region — us-east-2 or eu-central-1.

The public URL is the endpoint plus the bucket name:

https://br-<branch-id>.storage.c-1.<region>.aws.neon.tech/opencall-uploads

That, with no trailing slash, becomes NEXT_PUBLIC_R2_PUBLIC_BASE_URL.

The bucket lives on the branch

Neon storage branches with the project: deleting or resetting the branch takes the images with it. Point the variables at the branch that is actually serving the app.

Variables from this step

VariableValue
R2_BUCKETBucket name (opencall-uploads)
R2_ACCESS_KEY_IDtoken_id of the credential
R2_SECRET_ACCESS_KEYs3_secret_access_key
R2_ENDPOINTThe branch's storage endpoint
R2_REGIONus-east-2 or eu-central-1
NEXT_PUBLIC_R2_PUBLIC_BASE_URL<endpoint>/opencall-uploads

R2_ACCOUNT_ID stays empty on this path — it only applies to Cloudflare.

On this page