Neon is expanding into a backend: Object Storage, Functions, and AI Gateway now in beta
/APIs & SDKs/Buckets/Presign an upload or download for an object in a bucket
POST/projects/{project_id}/branches/{branch_id}/buckets/{bucket_name}/objects/{object_key}/presignbeta

Presign an upload or download for an object in a bucket

Returns a presigned URL that transfers bytes directly to or from the object's bucket on the specified branch, without the caller ever handling S3 credentials. The operation field selects the direction:

  • upload returns a presigned PUT URL (the caller PUTs the file bytes straight to url with the returned headers). Authorized with project write access.
  • download returns a presigned GET URL (the caller GETs the bytes straight from url). Authorized with project read access.

The platform mints a short-lived credential and builds the SigV4-signed URL against the branch's S3 data-plane host, returning it together with the HTTP method, any headers the caller must echo, and the URL's expiry.

Served by the user's session (no customer S3 credentials required).

Note: This endpoint is currently in Private Beta.

Markdown for AI context

Quick start

REST API - curl
curl "https://console.neon.tech/api/v2/projects/$PROJECT_ID/branches/$BRANCH_ID/buckets/$BUCKET_NAME/objects/$OBJECT_KEY/presign" \
  -X POST \
  -H "Authorization: Bearer $NEON_API_KEY"
Also available in
import { createNeonClient, raw } from '@neon/sdk';

const neon = createNeonClient({ apiKey: process.env.NEON_API_KEY });
const { data } = await raw.presignProjectBranchBucketObject({
  client: neon.client,
  path: {
    project_id: process.env.PROJECT_ID,
    branch_id: process.env.BRANCH_ID,
    bucket_name: process.env.BUCKET_NAME,
    object_key: process.env.OBJECT_KEY
  }
});

Parameters

Project ID
project_id
string

The Neon project ID

Branch ID
branch_id
string

The Neon branch ID

Bucket name
bucket_name
string

The bucket name

Object key
object_key
string

The object key. Keys may contain /; the / characters of nested keys must be percent-encoded (%2F) in the path segment.

Request body

1 required Required: operation.

Operation
operation
string

The transfer direction. upload returns a presigned PUT URL; download returns a presigned GET URL.

uploaddownload
Content type
content_type
string

The Content-Type to bind into the signed request. Only meaningful for upload: when set, the caller MUST send the same Content-Type header on the PUT, and the value is echoed back in the response headers. Ignored for download.

Expires in seconds
expires_in_seconds
integerdefault: 900

How long the presigned URL stays valid, in seconds. Defaults to 900 (15 minutes); capped at 604800 (7 days).

min: 1, max: 604800

Response

200

A presigned URL valid until expires_at. The caller transfers the object bytes by issuing method url with the returned headers.

Depth
"url": (string),req
"method": (string),req
"headers": (object),req
"expires_at": (string),reqdate-time

Errors

404

Bucket or branch not found

default

General error

This endpoint can return the standard Neon API error response.

Response fields

  • message Required. Human-readable error message.
  • code Required. Machine-readable error code.
  • request_id Optional. Request identifier for debugging. You can provide one with the X-Request-ID header.

Retry guidance

If no response is returned, the request may still have reached the server. This is why retry safety depends on the method and status code.

Idempotent methods (GET, HEAD, OPTIONS) are generally safe to retry after a network error or timeout. Non-idempotent methods (POST, PATCH, DELETE, PUT) can change state, so avoid automatic retries unless your workflow can tolerate duplicate effects.

Responses with 423 Locked or 503 Service Unavailable are safe to retry. 423 Locked means the resource is temporarily locked, usually because another operation is in progress.

Was this page helpful?

On this page

Copy neon init command