Features
Signed URLs
Grant temporary, authenticated access to private files — without exposing your API key.
The pattern
A signed URL embeds a cryptographic signature and expiry time. You generate it server-side with your Secret Key, then hand it to the client. The CDN validates the signature on every request and rejects expired or tampered URLs.
1
2
3
Client requests a file from your app
Your server checks auth — is the user allowed to see this file?
Your server calls CDNZero's create-link API
Returns a time-limited presigned_url (e.g. TTL = 15 min)
Your server redirects the client to the presigned URL
The CDN serves the file directly. Your API key never leaves the server.
Generating a signed URL
bash
curl -X POST https://api.cdnzero.com/collections/create-link \
-H "Authorization: Bearer YOUR_ACCESS_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_id": "file_abc123",
"file_type": "image",
"expiry": 900
}'Response
{
"file_id": "file_abc123",
"file_type": "image",
"expiry": 900,
"presigned_url": "https://cdn.cdnzero.com/files/abc123.png?X-Sig=...&X-Expires=..."
}Parameters
| Param | Type | Default | Description |
|---|---|---|---|
file_id | string | required | ID of the private file |
file_type | string | required | image, video, or document |
expiry | number | 3600 | TTL in seconds (max 86400 = 24 h) |
Next.js example
app/api/media/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
const fileId = req.nextUrl.searchParams.get('id')!;
const res = await fetch('https://api.cdnzero.com/collections/create-link', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CDNZERO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ file_id: fileId, file_type: 'image', expiry: 900 }),
});
const { presigned_url } = await res.json();
return NextResponse.redirect(presigned_url);
}Use signed URLs for anything user-specific: profile photos, invoices, private uploads. Keep the TTL short (5–15 minutes) for sensitive content.