Uploads and variants
Read GET /cdn/policy first. It returns formats, effective.allowedKinds, per-kind maxFileBytes, batch limits, video duration/pixels, namespace quotas and current credit rates. Limits are backend policy, with paid-tier and administrator overrides. The public GET /cdn/catalog returns tier defaults without account data.
Supported formats include JPEG, PNG, WebP, AVIF, GIF and restricted SVG; MP4, WebM, MOV and MKV; PDF, UTF-8 text, CSV, Markdown, JSON, RTF, Office Open XML and OpenDocument files; ZIP, gzip, tar, 7z and RAR. Use the live formats map as the exact allowlist. Macro-enabled Office files, HTML and executable formats are not supported.
SDK upload
The oblien SDK 2.11+ uses resumable uploads automatically and waits for a durable result. Keep API credentials on your backend.
import Oblien from 'oblien';
import { openAsBlob } from 'node:fs'; // Node 20+; avoids loading large files into RAM
const oblien = new Oblien({
clientId: process.env.OBLIEN_CLIENT_ID!,
clientSecret: process.env.OBLIEN_CLIENT_SECRET!,
});
const result = await oblien.cdn.upload({
data: await openAsBlob('./demo.mp4'),
filename: 'demo.mp4',
contentType: 'video/mp4',
}, {
namespace: 'customer-123', // optional; namespace keys are pinned by the API
idempotencyKey: 'customer-123-demo-v1',
video: { mode: 'compressed', preset: 'balanced' },
onProgress: progress => console.log(progress.phase, progress.receivedBytes),
});
console.log(result.file_id, result.url);Use uploadMany for a declared batch. processUrls({urls, namespace, maxBytes}) imports public HTTPS URLs through the same operation. Private, loopback, link-local and cloud metadata addresses are rejected, including redirected targets. Processing concurrency is controlled by Oblien.
Video modes
| Request | Stored result |
|---|---|
video: {mode: 'raw'} | One original video; no recompression |
video: {mode: 'compressed', preset: 'balanced'} | One complete compressed MP4; staged source removed |
video: {mode: 'variants', variants: ['compact', 'high'], keepOriginal: false} | Exactly the selected compressed versions |
Available presets are compact, balanced and high. Their dimensions and settings come from the provider policy. The current default is returned as provider.defaultVideoPreset. Variants may set primary to a retained version; full requires keepOriginal: true. Every retained output counts toward storage and monthly uploads. A truncated or oversized encode is rejected rather than published as a successful video.
Image variants
The default stores only the original. Image transformations are explicit:
await oblien.cdn.upload({ data: imageFile, filename: 'photo.jpg' }, {
variants: {
variantNames: ['thumb'],
customVariants: { thumb: { width: 320, height: 240, fit: 'cover', format: 'webp', quality: 80 } },
keepOriginal: true,
primary: 'full',
},
});Use keepOriginal: false with a produced primary variant to retain only transformed output. Opaque customer fields belong in metadata; processing options belong in variants or video.
Browser / HTTP contract
Your authenticated backend requests a permit:
POST https://api.oblien.com/cdn/token
X-Client-ID: <id>
X-Client-Secret: <secret>
Content-Type: application/json
Idempotency-Key: tenant-video-v1
{
"namespace": "customer-123",
"files": [{"name": "demo.mp4", "mime": "video/mp4", "size": 104857600}],
"video": {"mode": "compressed", "preset": "balanced"}
}maxBytes optionally sets the maximum stored-output reservation for the entire batch, including variants. It must fit current quota and batch limits. Omitting it lets the API choose a bounded reservation from the declared inputs and output plan. This reserves bytes, not a second credit balance.
Give the browser only token and upload.id. Use Authorization: Bearer <token> on these CDN endpoints:
Treat the permit as opaque. It contains the API's selected destination and worker, and the canonical edge routes it automatically. Never decode it to construct a bucket URL or send account credentials to a storage destination. This placement change requires no different SDK upload method.
Method and path at https://cdn.oblien.com/api | Purpose |
|---|---|
POST /uploads | Initialize or recover the declared operation; returns upload.files[] IDs and offsets |
PUT /uploads/:id/files/:fileId | Send binary chunk with Upload-Offset; optional Upload-Checksum is SHA-256 hex |
GET /uploads/:id | Read offsets, processing status, progress and result |
POST /uploads/:id/complete | Queue validation and processing after all source bytes arrive |
Respect upload.chunkBytes, currently 8 MiB. Duplicate chunks with identical offset and bytes are acknowledged once; changed bytes return a conflict. A successful upload has status: 'ready' and result[]. States such as queued, processing and publishing are pending. Resume with oblien.cdn.resumeUpload(token, originalFiles, options) or poll using waitForUpload. An aborted client request can be resumed; it does not refund already stored usage.
For small integrations, POST /api (field file) and /api/multiple (field files) accept multipart requests up to 32 MiB. Larger files use chunks. Multipart may return 202 {success:true, upload}; this means processing was accepted. Poll GET /api/uploads/:id with the original permit until upload.status is ready, then use upload.result[].url. If processing fails, display upload.error instead of starting another upload automatically.
A completed single-file response preserves the original top-level {success, recorded, file_id, url, filename, size, mime, variants} fields. Use url for delivery; data.url remains available as a compatibility alias for the same receipt. Completed batches return {success, recorded, files, totalCount}, with a URL on each file. Retrying with the original permit returns the same operation and files.
Errors
Errors include a stable error code and a customer-safe message. Important cases: cdn_media_not_allowed, cdn_file_too_large, cdn_quota_exceeded, cdn_concurrent_uploads, insufficient_credits, quota_exceeded, upload_manifest_mismatch, idempotency_conflict, upload_expired, and temporary cdn_unavailable or cdn_capacity_unavailable. Retry a temporary failure using the same operation. Correct invalid input before creating a new one.