Story0.API

Reference

Limits and retention

Media sizes, request rates, field limits, supported inputs, and how long Story0 keeps each kind of data.

This page collects every limit in one place, with what happens when you reach it.

Media

Limit Value What happens past it
Video length 20 minutes (1,200 seconds) The asset, or the job reading it, fails with unsupported_input.
File size 2 GB (2,147,483,648 bytes) POST /v1/uploads with a larger bytes, completing a larger upload, or fetching a larger URL fails with unsupported_input.
Minimum billable length 30 seconds Shorter videos are billed as 30 seconds.
URL download time 10 minutes The fetch fails with source_unavailable. Upload the file instead.
URL redirects 5 The fetch fails with source_unavailable.
Upload chunk size Multiples of 256 KiB (262,144 bytes), except the last chunk Use other sizes only for the final chunk. The SDKs round chunk sizes for you.
Upload session lifetime 24 hours Open a new session.

Supported inputs

  • Video files in common container formats and codecs, as long as the file has a video stream and a measurable duration. Story0 identifies the format from the file itself, whatever its extension or declared content type. A file it can't read fails with media_unreadable; if it plays elsewhere, re-encoding it to H.264 in an MP4 container usually helps.
  • Upload content types: any video/* type or application/octet-stream.
  • URLs: direct http or https links to a video file on a public address, without credentials in the URL. Platform pages (YouTube, Instagram and TikTok links, for example) and web pages aren't fetched. See Uploading media.
  • Audio is detected and reported in media.has_audio, but it isn't analyzed: results are based on what's visible in sampled frames.

Requests

Limit Value
Read requests (GET) 1,200 a minute per account
Write requests (POST, PUT, DELETE) 300 a minute per account
Active jobs 20 queued or running per account, test and live combined
Long-poll wait on GET /v1/jobs/{id} 0 to 30 seconds
Page size (limit) for assets, jobs and events 1 to 100, default 20
Webhook deliveries listed per endpoint The 50 most recent
GET /v1/usage window (days) 1 to 90, default 30
Enabled webhook endpoints 10 per account
Active API keys 25 per account

Rate limits are counted in one-minute windows and tracked by each API server separately, so treat them as approximate. Going over either one returns 429 rate_limited with a Retry-After header giving the seconds until the window resets; the SDKs wait that long before retrying.

The active-job limit returns 429 concurrency_limit with Retry-After: 5. It counts jobs that are queued or running, so the way past it is to let jobs finish before you submit more.

Request fields

Field Limit
instruction 3 to 2,000 characters
labels (partition) 2 to 12
categories (screening) 1 to 20
Label and category key, uncertainty.label 1 to 40 characters: a lowercase letter, then lowercase letters, digits or underscores
Label and category description 1 to 500 characters
sampling.fps 0.1 to 4
Frames inspected per segmentation At most 600
range.start 0 or more, and inside the video
range.end More than 0 and more than range.start; clamped to the video's duration
constraints.min_seconds More than 0, up to 600
constraints.max_seconds More than 0, up to 3,600
constraints.max_segments 1 to 500
metadata Up to 20 pairs of strings, each value up to 500 characters
billing.max_charge.amount A decimal string with up to 6 decimal places; currency must be USD
Idempotency-Key header 1 to 255 characters from A–Z a–z 0–9 _ . : -
X-Request-Id header 8 to 80 characters from A–Z a–z 0–9 _ -
Upload filename Up to 255 characters
Upload content_type Up to 100 characters
Webhook endpoint description Up to 200 characters
Feedback comment, actor, label Up to 2,000, 200 and 40 characters

A request that breaks one of these limits is refused with 422 invalid_request, and the errors array points at the field. The 600-frame limit is the exception: it isn't validated up front, so choose sampling.fps so that the rate multiplied by the range length stays at or below 600. See Segmentation.

Retention

What Kept for Afterwards
Asset media 7 days from the asset's creation, or until a queued or running job that needs it finishes The media is deleted and the asset returns 404 not_found.
Results 30 days from creation GET returns 410 result_expired. The job record remains.
Idempotency keys 7 days The same key starts a new job.
Upload sessions 24 hours Open a new session.
Estimates Meant to be current for 1 hour (expires_at) Request a new estimate.
Webhook deliveries Up to 18 attempts over about 17 hours The delivery is marked failed; the event stays in GET /v1/events.

Every asset and result states its own expiry in retention, so you never need to compute it. You can delete media sooner with DELETE /v1/assets/{id}; results stay available until their own expiry.

Timeouts and defaults

Item Value
Hold for a request whose duration isn't known yet, without max_charge $2.00
Time your webhook endpoint has to answer 15 seconds
Webhook signature tolerance in the SDK helpers 5 minutes
Automatic job retries before a job fails Up to 5 attempts
SDK network timeout per request 60 seconds
SDK automatic retries 2
SDK wait for a job 10 minutes
SDK wait for an asset to become ready 5 minutes