Storage API
Base URL: https://storage-api.pcampus.co
Upload
POST /v1/upload
Direct upload (server-side).
POST https://storage-api.pcampus.co/v1/upload
Authorization: Bearer <pip_api_key>
x-tenant-id: your-tenant-id
Content-Type: multipart/form-data
file=@product-photo.jpg&bucket=products&key=PROD-001/main.jpg&public=trueResponse:
{
"objectId": "obj_xxx",
"bucket": "products",
"key": "PROD-001/main.jpg",
"url": "https://cdn.pcampus.co/products/PROD-001/main.jpg",
"size": 204800,
"mimeType": "image/jpeg",
"public": true,
"uploadedAt": "2026-07-15T10:00:00.000Z"
}POST /v1/presign
Generate a presigned URL for direct client upload (recommended for large files).
POST https://storage-api.pcampus.co/v1/presign
Authorization: Bearer <pip_api_key>
x-tenant-id: your-tenant-id
{
"bucket": "products",
"key": "PROD-001/gallery-01.jpg",
"mimeType": "image/jpeg",
"expiresIn": 900,
"public": true
}Response:
{
"uploadUrl": "https://storage-api.pcampus.co/presigned/abc123...",
"objectUrl": "https://cdn.pcampus.co/products/PROD-001/gallery-01.jpg",
"expiresAt": "2026-07-15T10:15:00.000Z",
"method": "PUT"
}The client can PUT directly to uploadUrl with the specified Content-Type:
await fetch(uploadUrl, {
method: 'PUT',
headers: { 'Content-Type': 'image/jpeg' },
body: fileBlob
})Download & Access
GET /v1/objects/:bucket/:key
Retrieve an object or redirect to the CDN.
GET https://storage-api.pcampus.co/v1/objects/products/PROD-001/main.jpg
Authorization: Bearer <pip_api_key> ← required only for private bucketsPublic bucket: Accessible directly via CDN URL without a token.
https://cdn.pcampus.co/products/PROD-001/main.jpg
POST /v1/presign/download
Generate a presigned URL for downloading a private object (time-limited).
POST https://storage-api.pcampus.co/v1/presign/download
Authorization: Bearer <pip_api_key>
{
"bucket": "prescriptions",
"key": "RX-001/scan.pdf",
"expiresIn": 300
}Image Transformation
Public images can be transformed via URL params directly from the CDN:
https://cdn.pcampus.co/{bucket}/{key}?w=400&h=300&fit=cover&q=80&f=webp| Param | Type | Description |
|---|---|---|
w | number | Width (px) |
h | number | Height (px) |
fit | string | cover | contain | fill | inside | outside |
q | number | Quality 1–100 (default 85) |
f | string | Format: webp | jpeg | png | avif |
Examples:
# Thumbnail 200x200
https://cdn.pcampus.co/products/PROD-001/main.jpg?w=200&h=200&fit=cover&f=webp
# Full width, preserve ratio
https://cdn.pcampus.co/products/PROD-001/main.jpg?w=800&f=webp&q=90Delete
DELETE /v1/objects/:bucket/:key
DELETE https://storage-api.pcampus.co/v1/objects/products/PROD-001/old.jpg
Authorization: Bearer <pip_api_key>
x-tenant-id: your-tenant-idBuckets
GET /v1/buckets
POST /v1/buckets
POST https://storage-api.pcampus.co/v1/buckets
Authorization: Bearer <pip_api_key>
x-tenant-id: your-tenant-id
{
"name": "prescriptions",
"public": false,
"region": "ap-southeast-1"
}DELETE /v1/buckets/:bucketName
Deleting a bucket deletes all objects inside it — use with caution.