PlatformXeDocs
Get API Key

Upload Files

API reference for uploading files via direct upload, signed URLs, or external URL registration.

PlatformXe supports three upload methods depending on your architecture: direct server-side upload, signed URLs for client-side upload, and external URL registration.

Direct upload

Upload a file directly from your server to PlatformXe.

POST /api/v1/storage/media/upload

Scope: storage:upload

Content-Type: multipart/form-data

Request body

FieldTypeRequiredDescription
fileFileYesThe file to upload
folderstringNoTarget folder path (e.g. invoices/2026)
accessstringNoAccess level: public, authenticated, or private. Default: public
tagsstringNoComma-separated tags for organization

Response

{
  "success": true,
  "data": {
    "fileId": "file_abc123def456",
    "url": "https://cdn.platformxe.com/org_123/invoices/2026/receipt.pdf",
    "format": "pdf",
    "size": 245760,
    "width": null,
    "height": null,
    "createdAt": "2026-04-05T14:30:00.000Z"
  }
}

curl

curl -X POST https://api.platformxe.com/api/v1/storage/media/upload \
  -H "x-api-key: pxk_live_your_api_key_here" \
  -F "file=@/path/to/image.png" \
  -F "folder=products/thumbnails" \
  -F "access=public" \
  -F "tags=product,thumbnail"

SDK

import { PlatformXe } from '@caldera/platformxe-sdk';

const px = new PlatformXe({ apiKey: 'pxk_live_your_api_key_here' });

const result = await px.storage.upload({
  file: fileBuffer,
  folder: 'products/thumbnails',
  access: 'public',
  tags: ['product', 'thumbnail'],
});

console.log(result.data.url);
// "https://cdn.platformxe.com/org_123/products/thumbnails/image.png"

Signed upload

Generate a pre-signed URL so clients can upload files directly from the browser without routing through your server.

POST /api/v1/storage/media/sign-upload

Scope: storage:upload

Request body

FieldTypeRequiredDescription
filenamestringYesOriginal filename
contentTypestringYesMIME type of the file (e.g. image/png)
folderstringNoTarget folder path
accessstringNoAccess level. Default: public
maxSizenumberNoMaximum allowed file size in bytes

Response

{
  "success": true,
  "data": {
    "uploadUrl": "https://upload.platformxe.com/signed/abc123...",
    "fileId": "file_pending_abc123",
    "expiresAt": "2026-04-05T15:30:00.000Z"
  }
}

Signed upload URLs expire after 60 minutes. The client must complete the upload before expiry or request a new signed URL.

curl

# Step 1: Get the signed URL
curl -X POST https://api.platformxe.com/api/v1/storage/media/sign-upload \
  -H "Content-Type: application/json" \
  -H "x-api-key: pxk_live_your_api_key_here" \
  -d '{
    "filename": "avatar.jpg",
    "contentType": "image/jpeg",
    "folder": "avatars",
    "maxSize": 5242880
  }'

# Step 2: Upload to the signed URL (from client)
curl -X PUT "https://upload.platformxe.com/signed/abc123..." \
  -H "Content-Type: image/jpeg" \
  --data-binary @avatar.jpg

Register external URL

Register a file that is already hosted elsewhere. PlatformXe indexes the file and optionally copies it to CDN storage.

POST /api/v1/storage/media/register

Scope: storage:upload

Request body

FieldTypeRequiredDescription
urlstringYesPublicly accessible URL of the file
filenamestringNoDisplay name for the file
folderstringNoTarget folder path
copyToCdnbooleanNoIf true, download and re-host on CDN. Default: false

Response

{
  "success": true,
  "data": {
    "fileId": "file_ext_abc123",
    "url": "https://cdn.platformxe.com/org_123/imported/avatar.jpg",
    "sourceUrl": "https://example.com/avatar.jpg",
    "copied": true,
    "createdAt": "2026-04-05T14:30:00.000Z"
  }
}

SDK

const result = await px.storage.register({
  url: 'https://example.com/product-photo.jpg',
  folder: 'products',
  copyToCdn: true,
});

console.log(result.data.fileId);
// "file_ext_abc123"

Use copyToCdn: true if the external URL may become unavailable. The file is downloaded and stored on PlatformXe CDN for reliable access.

Error responses

CodeDescription
BAD_REQUESTMissing file, unsupported file type, or exceeds size limit
FORBIDDENAPI key does not have the storage:upload scope
RATE_LIMITEDRate limit exceeded for this API key
MODERATION_REJECTEDFile was rejected by content moderation