Streamlet Platform Documentation

RESTful API Reference

Use Streamlet directly over HTTP when you want full control over upload, processing, captions, image hosting, storage, and backend workflows.

Templates

Use the official Streamlet template repository when you want a faster starting point for frontend apps or backend REST API services. Open Streamlet-Templates.

TemplateStackPurpose
Next.js Video UploadNext.js 16Frontend starter for Streamlet SDK-based upload and processing flows.
Next.js Image UploadNext.js 16Frontend starter for image hosting and CDN delivery.
Next.js PlayerNext.js 16Playback-focused Streamlet player starter.
Node.js Express REST APINode.js / ExpressProxy Streamlet REST API routes from an Express backend.
Go REST APIGoStreamlet REST wrapper for Go services.
Python REST APIPython / FastAPIFastAPI example for Streamlet uploads and status endpoints.
Rust REST APIRust / AxumRust backend starter for Streamlet REST integrations.
Java REST APIJava / Spring BootSpring Boot backend starter for Streamlet APIs.

Authentication

Streamlet API-key routes require both the API key and the account number. These match the middleware already used in the main Streamlet backend.

x-streamlet-api-key and x-streamlet-account-number must be sent on every protected request.

Upload Video

POST to /api-key/start-video-processing with multipart form data. Upload the source video, set the title, and optionally enable captions, original-file retention, and high-resolution output. The server responds immediately with a videoId — use the Status API to poll for completion.

Use the uploadType field to choose how the file is handled.uploadType=streaming (the default) runs the full processing pipeline: transcoding into an adaptive HLS ladder, thumbnails and optional captions.uploadType=private uploads the file directly to storage with no processing — the response returns status="completed" right away with a streamUrl pointing at the stored file. All processing options below are ignored for private uploads.

Pass enable2kOutput=true (Builder and Pro plans) to add a 1440p (2K) rendition to the HLS adaptive ladder. Pass enable4kOutput=true (Pro plan only) to add a 2160p (4K) rendition. Both flags are silently ignored on plans that do not support them.

Create processing job

JavaScript

const formData = new FormData();
formData.append("video", fileInput.files[0]);
formData.append("videoTitle", "Launch Demo");
formData.append("saveOriginalFile", "true");
formData.append("autoAudioEnhancement", "true");
formData.append("videoOptimization", "storage_saver");
formData.append("enableCaption", "true");
formData.append("engCaption", "true");
formData.append("hindiCaption", "true");

const response = await fetch("https://api.streamlet.in/api-key/start-video-processing", {
  method: "POST",
  headers: {
    "x-streamlet-api-key": "sk_streamlet_live_xxxxxxxxxxxxxx",
    "x-streamlet-account-number": "681b58c58d8c0a55b7c64b2c"
  },
  body: formData
});

const data = await response.json();
console.log(data);

Queued upload response

JSON

{
  "success": true,
  "videoId": "Launch Demo-1775211037986",
  "userId": "681b58c58d8c0a55b7c64b2c",
  "status": "queued",
  "message": "Video uploaded and queued for processing",
  "statusUrl": "/video-processing-status/Launch%20Demo-1775211037986"
}

Plan Limits

Streamlet enforces storage and video duration limits per plan. Uploads that exceed these caps are rejected before any processing begins — both from the dashboard and from the API.

Video duration limit

Free-plan accounts may only upload videos up to 6 minutes (360 seconds). Videos longer than this are rejected with HTTP 403 and the error code DURATION_LIMIT_EXCEEDED. Paid plans have no duration restriction.

PlanMax video durationStorageMax resolution2K output4K outputCaption quota / monthWatermark
free6 minutes1 GB480pNoNo10 minutesForced — streamlet.in
starterUnlimited50 GB720pNoNo5 hoursOptional custom text
builderUnlimited200 GB2K (1440p)enable2kOutput=trueNo25 hoursOptional custom text
proUnlimited500 GB4K (2160p)enable2kOutput=trueenable4kOutput=true50 hoursOptional custom text

Caption quota

Each plan includes a monthly caption quota based on the total duration of videos processed with captions enabled. The quota resets on the 1st of each month. Requests that would exceed the quota are rejected with HTTP 403 and the error code CAPTION_QUOTA_EXCEEDED.

Duration limit error (HTTP 403)

JSON

{
  "success": false,
  "error": "Video duration (420s) exceeds the 6-minute limit for the free plan. Upgrade to process longer videos.",
  "code": "DURATION_LIMIT_EXCEEDED"
}

Caption quota exceeded error (HTTP 403)

JSON

{
  "success": false,
  "error": "Caption quota exhausted for this month. Upgrade your plan or wait for the monthly reset.",
  "code": "CAPTION_QUOTA_EXCEEDED"
}

Watermark

Streamlet enforces watermark rules per plan:

  • Free plan — every video is automatically stamped with a streamlet.in watermark. This cannot be disabled and the enableWatermark / watermarkText fields are ignored.
  • Paid plans (Starter, Builder, Pro) — the watermark is fully optional. Pass enableWatermark=true with a custom watermarkText (max 60 characters) to overlay your own text, or omit / pass enableWatermark=false to encode with no watermark at all.

Upload with custom watermark (paid plans)

JavaScript

const formData = new FormData();
formData.append("video", fileInput.files[0]);
formData.append("videoTitle", "Launch Demo");
// Paid plan: add a custom watermark
formData.append("enableWatermark", "true");
formData.append("watermarkText", "© MyBrand 2024");
// Paid plan: disable watermark entirely — omit or set to "false"
// formData.append("enableWatermark", "false");

const response = await fetch("https://api.streamlet.in/api-key/start-video-processing", {
  method: "POST",
  headers: {
    "x-streamlet-api-key": "sk_streamlet_live_xxxxxxxxxxxxxx",
    "x-streamlet-account-number": "681b58c58d8c0a55b7c64b2c"
  },
  body: formData
});

const data = await response.json();
console.log(data);
FieldTypeDescription
enableWatermarkstring"true" / "false"Paid plans only. Set to "true" to add a custom watermark, or "false" / omit to encode with no watermark. Ignored for free-plan accounts — streamlet.in is always applied.
watermarkTextstring (max 60 chars)Custom text to overlay on the video. Only applied when enableWatermark=true on a paid plan.

Upload Image

POST to /api-key/upload-image with a single image file. Streamlet auto-rotates, resizes to a max of 2000 px wide, converts to WebP at quality 85, and returns back you the processed image. The response includes a ready-to-use cdnUrl and the final pixel dimensions.

Accepted formats: JPEG, PNG, WebP, AVIF, GIF. Maximum upload size is 20 MB. Storage counts toward the account quota.

Upload an image

JavaScript

const formData = new FormData();
formData.append("image", fileInput.files[0]);

const response = await fetch("https://api.streamlet.in/api-key/upload-image", {
  method: "POST",
  headers: {
    "x-streamlet-api-key": "sk_streamlet_live_xxxxxxxxxxxxxx",
    "x-streamlet-account-number": "681b58c58d8c0a55b7c64b2c"
  },
  body: formData
});

const data = await response.json();
console.log(data.cdnUrl);
// "https://cdn.streamlet.in/681b.../images/product-banner-1775211037986.webp"

Image upload response

JSON

{
  "success": true,
  "imageId": "product-banner-1775211037986",
  "cdnUrl": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/images/product-banner-1775211037986.webp",
  "streamletKey": "681b58c58d8c0a55b7c64b2c/images/product-banner-1775211037986.webp",
  "width": 1200,
  "height": 630,
  "sizeBytes": 84320
}

Upload Document

POST to /api-key/upload-document with a single PDF file. Streamlet stores the file and returns a permanent CDN URL instantly — no processing queue, no polling needed. Use the URL directly in your app, email, or embed it in a viewer.

Accepted format: PDF only. Maximum upload size is 50 MB. Storage counts toward the account quota.

Upload a PDF document

JavaScript

const formData = new FormData();
formData.append("document", fileInput.files[0]);

const response = await fetch("https://api.streamlet.in/api-key/upload-document", {
  method: "POST",
  headers: {
    "x-streamlet-api-key": "sk_streamlet_live_xxxxxxxxxxxxxx",
    "x-streamlet-account-number": "681b58c58d8c0a55b7c64b2c"
  },
  body: formData
});

const data = await response.json();
console.log(data.cdnUrl);
// "https://cdn.streamlet.in/681b.../documents/product-spec-1775211037986.pdf"

Document upload response

JSON

{
  "success": true,
  "documentId": "product-spec-1775211037986",
  "cdnUrl": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/documents/product-spec-1775211037986.pdf",
  "streamletKey": "681b58c58d8c0a55b7c64b2c/documents/product-spec-1775211037986.pdf",
  "originalFilename": "product-spec.pdf",
  "sizeBytes": 245760
}

Video Status

GET /api-key/video-processing-status/:videoId to fetch the current status for one video. Use the returned videoId from the upload response.

Get processing status

JavaScript

const response = await fetch(
  "https://api.streamlet.in/api-key/video-processing-status/your_video_id",
  {
    headers: {
      "x-streamlet-api-key": "sk_streamlet_live_xxxxxxxxxxxxxx",
      "x-streamlet-account-number": "681b58c58d8c0a55b7c64b2c"
    }
  }
);

const data = await response.json();
console.log(data);

Completed status response

JSON

{
  "success": true,
  "videoId": "Launch Demo-1775211037986",
  "userId": "681b58c58d8c0a55b7c64b2c",
  "videoTitle": "Launch Demo",
  "title": "Launch Demo",
  "visibility": "Private",
  "fileName": "product-demo.mp4",
  "fileSizeBytes": 6681892,
  "fileMimeType": "video/mp4",
  "status": "completed",
  "queuedAt": "2026-04-03T10:10:39.888Z",
  "keepOriginal": true,
  "autoAudioEnhancement": true,
  "generateCaptions": true,
  "captionLanguages": ["english", "hindi"],
  "originalVideoUrl": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/original/product-demo.mp4",
  "streamUrl": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/master.m3u8",
  "thumbnail": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/thumbnail.jpg",
  "audioPlaylistUrl": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/vaudio/playlist.m3u8",
  "durationSeconds": 27.814286,
  "captions": {
    "en": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/captions.en.vtt",
    "hi": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/captions.hi.vtt"
  },
  "chapters": {
    "vtt": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/chapters.vtt",
    "json": "https://cdn.streamlet.in/681b58c58d8c0a55b7c64b2c/video/Launch%20Demo-1775211037986/processed/chapters.json"
  },
  "completedAt": "2026-04-03T10:12:14.748Z"
}

Health API

GET /health to verify service uptime and queue visibility. This is useful for infrastructure checks before sending upload traffic.

curl "https://api.streamlet.in/health"