NetraFlow

Uploads

Analyze your own video files instead of a platform URL.

Three steps: get a presigned URL, PUT the file to it, then create a job with the returned key. On every plan; size, format and how many unused uploads you can hold are on Limits.

1. Request a presigned URL

POST /v1/uploads/presign

Returns HTTP 200 with the put_url to upload to and the key to create the job with.

PropTypeDescription
content_typestringOne of video/mp4, video/quicktime or video/webm.
size_bytesintegerExact file size in bytes. Up to 500 MB.
curl -X POST https://api.netraflow.com/v1/uploads/presign \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: sk_live_your_key_here" \
  -d '{
    "content_type": "video/mp4",
    "size_bytes": 18234112
  }'
{
  "data": {
    "put_url": "https://<upload-host>/uploads/...?X-Amz-Signature=...",
    "key": "uploads/ten_abc123/8b1d6c1e-2f4a-4c57-9d3e-5a7b1c9e0f42.mp4"
  },
  "meta": { "request_id": "req_xyz789" }
}

2. Upload the file

PUT the raw bytes to put_url with the Content-Type you presigned, within 10 minutes. The body must be exactly size_bytes long.

curl -X PUT "$PUT_URL" \
  -H "Content-Type: video/mp4" \
  --data-binary @my-video.mp4

3. Create the job

Pass upload_key instead of url, plus upload_filename for the video title.

curl -X POST https://api.netraflow.com/v1/jobs \
  -H "Content-Type: application/json" \
  -H "X-Api-Key: sk_live_your_key_here" \
  -d '{
    "upload_key": "uploads/ten_abc123/8b1d6c1e-2f4a-4c57-9d3e-5a7b1c9e0f42.mp4",
    "upload_filename": "my-video.mp4",
    "capabilities": ["transcription"]
  }'
{
  "data": {
    "job_id": "job_abcdefghij123456",
    "status": "pending",
    "url": "uploads/ten_abc123/8b1d6c1e-2f4a-4c57-9d3e-5a7b1c9e0f42.mp4",
    "platform": "upload",
    "capabilities": ["transcription"],
    "language": null,
    "video_title": "my-video.mp4",
    "video_duration_seconds": null,
    "video_thumbnail_url": null,
    "credits_estimated": 2,
    "credits_charged": null,
    "processing_seconds": null,
    "return_proof": true,
    "follow_id": null,
    "created_at": "2026-04-03T12:00:00.000Z",
    "started_at": null,
    "completed_at": null
  },
  "meta": { "request_id": "req_xyz789" }
}

The job has platform: "upload" and your upload_key as its url, and is like any other job from there. Send both url and upload_key, neither, or a key that isn't yours, and it is VALIDATION_FAILED (422). Batches take uploads in their uploads array.

Reuse. Any number of jobs can use the same key while the file exists, each charged as usual. Pass the first job as from_job to reuse its work.

Deletion. A file is deleted 2 days after upload at most, sooner once no job needs it: a day after its last job completed, or within seconds when it failed or was cancelled. A job on a deleted file fails with UPLOAD_NOT_FOUND; one on a file that isn't a video fails with EXTRACTION_FAILED. Neither is charged.

On this page