Storage
Presigned URLs
Generate time-limited signed URLs that allow anyone to upload or download objects directly — without exposing your credentials. Ideal for browser uploads, mobile apps, and sharing private files.
How Presigned URLs Work
A presigned URL is a time-limited, self-authenticating URL that grants temporary access to a specific object. The URL embeds the access credentials as query parameters using AWS Signature V4, so the recipient doesn't need API keys.
Presigned Uploads
Let users upload files directly to storage from their browser or app. No server-side proxy needed — the client PUTs directly to the signed URL.
Presigned Downloads
Share private files with time-limited links. Give a user a URL to download their invoice, report, or asset — the link expires after the set duration.
Two Ways to Generate Presigned URLs
1 Using S3 SDKs (recommended)
Generate presigned URLs client-side or server-side using any AWS S3 SDK. This is the standard approach and works identically to AWS S3. Requires your access key and secret key.
2 Using the Edge API
Call POST /api/storage/buckets/:name/presign with your Edge API token.
The server generates the presigned URL for you — no S3 credentials needed on the client.
SDK Examples
JavaScript / Node.js
Install the S3 client and presigner:
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner Generate a presigned upload URL
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
const client = new S3Client({
endpoint: 'https://storage.edge.network',
region: 'us-east-1',
forcePathStyle: true,
credentials: {
accessKeyId: process.env.EDGE_ACCESS_KEY,
secretAccessKey: process.env.EDGE_SECRET_KEY
}
})
// Generate a presigned upload URL (valid for 1 hour)
const url = await getSignedUrl(client, new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'uploads/photo.jpg',
ContentType: 'image/jpeg',
}), { expiresIn: 3600 }) Generate a presigned download URL
import { GetObjectCommand } from '@aws-sdk/client-s3'
import { getSignedUrl } from '@aws-sdk/s3-request-presigner'
// Generate a presigned download URL (valid for 15 minutes)
const url = await getSignedUrl(client, new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'invoices/invoice-001.pdf',
}), { expiresIn: 900 }) Upload from a browser using the presigned URL
// Browser: upload a file using the presigned URL
const fileInput = document.querySelector('input[type="file"]')
const file = fileInput.files[0]
const response = await fetch(presignedUrl, {
method: 'PUT',
body: file,
headers: {
'Content-Type': file.type,
},
})
if (response.ok) {
console.log('Upload complete')
}
Python
Generate a presigned upload URL
import boto3
client = boto3.client(
's3',
endpoint_url='https://storage.edge.network',
aws_access_key_id=os.environ['EDGE_ACCESS_KEY'],
aws_secret_access_key=os.environ['EDGE_SECRET_KEY'],
region_name='us-east-1'
)
# Generate a presigned upload URL (valid for 1 hour)
url = client.generate_presigned_url(
'put_object',
Params={
'Bucket': 'my-bucket',
'Key': 'uploads/photo.jpg',
'ContentType': 'image/jpeg',
},
ExpiresIn=3600
)
print(url) Generate a presigned download URL
# Generate a presigned download URL (valid for 15 minutes)
url = client.generate_presigned_url(
'get_object',
Params={
'Bucket': 'my-bucket',
'Key': 'invoices/invoice-001.pdf',
},
ExpiresIn=900
)
print(url)
cURL
Upload with a presigned URL
# Upload using the presigned URL
curl -X PUT "$PRESIGNED_URL" \
-H "Content-Type: image/jpeg" \
--data-binary @photo.jpg Download with a presigned URL
# Download using the presigned URL
curl -o invoice.pdf "$PRESIGNED_URL" Edge API
If you don't want to manage S3 credentials on the client, you can generate presigned URLs server-side via the Edge API using your account's Bearer token.
POST /api/storage/buckets/:name/presign
| Parameter | Type | Required | Description |
|---|---|---|---|
| key | string | Yes | Object key (path) within the bucket |
| action | string | No | download (default) or upload |
| expires | string | No | Duration: 15m, 1h (default), 7d (max) |
Generate an upload URL
# Generate a presigned upload URL via the Edge API
curl -X POST https://api.edge.network/api/storage/buckets/my-bucket/presign \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "uploads/photo.jpg",
"action": "upload",
"expires": "1h"
}'
# Response:
# {
# "url": "https://storage.edge.network/my-bucket/uploads/photo.jpg?X-Amz-Algorithm=...",
# "method": "PUT",
# "expires": "2026-03-12T01:00:00Z"
# } Generate a download URL
# Generate a presigned download URL via the Edge API
curl -X POST https://api.edge.network/api/storage/buckets/my-bucket/presign \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"key": "invoices/invoice-001.pdf",
"expires": "15m"
}' Common Use Cases
User avatar uploads
Generate a presigned PUT URL server-side, return it to the browser, and let the user upload their photo directly to storage.
Private file sharing
Generate a presigned GET URL for an invoice or report. Send the link to the user — it expires after the set duration.
Mobile app uploads
Your backend generates a presigned URL, sends it to the mobile app, and the app uploads directly. No proxy, no extra bandwidth on your server.
Third-party integrations
Give a partner or webhook a presigned URL to upload data into your bucket without sharing credentials.
Security Considerations
-
URLs are bearer tokens. Anyone with the URL can use it until it expires. Share them over secure channels (HTTPS, encrypted messages). -
Keep expiry times short. Use the minimum duration needed — 15 minutes for downloads, 1 hour for uploads. Maximum is 7 days. -
URLs are scoped to a single object. A presigned URL for photos/image.jpgcannot be used to access any other object. -
Revoking access. Delete or rotate the access key used to generate the URL. All presigned URLs created with that key become invalid immediately.