Plans & limits

Workspace plans control the monthly credit pool, queue priority, and operational caps on video length and transcript size. Limits are enforced at job creation (quota) and during worker processing (duration, storage).

Workspace plans

PlanMonthly creditsvs FreeQueue priorityPer-video length
free10,000lowUp to 1 hour
starter20,000lowUp to 1 hour
pro50,000normalUp to 1 hour
business200,00020×highUp to 1 hour
enterpriseUnlimited (fair use)highUp to 1 hour by default; longer media available on request

New workspaces default to free. Paid tiers are assigned manually — contact your account team. Plan is reflected on each job as priority (set at creation, not overridable in the request body).

Plan catalog and per-action credit costs: GET /v1/billing/limits returns plans (monthlyCredits, multiplierVsFree) and creditCosts. With a workspace API key, GET /v1/workspace or GET /v1/workspace/usage returns the unified pool (limit, used, remaining, byService[]). GET /v1/projects/{projectId}/usage returns per-project consumption and optional creditLimit.

Monthly credit pool

All billable actions draw from one workspace credit pool for the current billing period. Each action costs credits according to creditCosts on GET /v1/billing/limits (defaults below):

  • POST /v1/jobs with serviceType: transcription 100 credits per job.
  • POST /v1/jobs with serviceType: indexer 10 credits per transcriptionId in input.transcriptionIds (up to 50 per job).
  • POST /v1/jobs with serviceType: clip_generation 1 credit per clip in input.options.maxClips.
  • POST /v1/jobs with serviceType: thumbnail 10 credits per variant in input.options.thumbnailCount (1–3).
  • POST /v1/jobs with serviceType: metadata 10 credits per job.
  • POST /v1/jobs with serviceType: summarization 20 credits per job.
  • POST /v1/jobs with serviceType: translation 20 credits per job.
  • POST /v1/catalog/search1 credit per search request.

Credits are reserved when the API accepts the request (job queued or search executed). Failed jobs after queueing still count toward usage.

When the pool is exhausted, the API returns 403 with error.code: quotaExceeded:

{
  "data": null,
  "error": {
    "code": "quotaExceeded",
    "message": "credit limit: need 100, 0 remaining this period; resets at 2026-06-01T00:00:00.000Z"
  },
  "metadata": { ... }
}

Check balances before bulk loops via GET /v1/workspace/usage (remaining on the unified pool). Projects may optionally set creditLimit for a sub-cap within the workspace pool.

This is an envelope error (not job.error). Integrators should surface it before polling. See Errors.

API rate limits (project & workspace keys)

Programmatic callers using project or workspace API keys share per-key HTTP rate limits (rolling one-minute window). Dashboard JWT sessions and platform admin routes are not capped this way — job volume is gated by monthly quota instead.

MethodsLimit (per API key)
GET, HEAD10,000 / minute
POST, PUT, PATCH, DELETE50 / minute

Read and write counters are independent — heavy polling on GET /v1/jobs/… does not consume your write budget. On exceed, the API returns 429 with error.code: rateLimited.

Max source duration & word timings

Max source duration is configured in platform settings (default 1 hour). Sources longer than this fail with duration_exceeded. Word-level timings are stored through the same limit — longer jobs return segments without per-word timings.

The worker rejects sources longer than this limit before transcription runs. Duration is checked from local media after download. Configure the limit in platform admin settings (transcription.maxSourceDurationSec).

Live values: GET /v1/transcription/policy data.plans.free.maxSourceDurationSec and data.plans.enterprise.maxSourceDurationSec. There is no duration field on POST /v1/jobs — invalid length is discovered asynchronously. Poll the job; on failure, status is failed and error.code is duration_exceeded.

{
  "code": "duration_exceeded",
  "message": "Video duration 7200.0s exceeds limit 3600s (checked at local_probe)"
}

Transcript size

Completed transcripts are stored in MongoDB with a BSON size guard (default ~15 MiB estimated before write). Extremely long or word-dense outputs fail at persist time with transcript_too_large on the job — the job ends failed even if the engine finished transcribing.

{
  "code": "transcript_too_large",
  "message": "Transcription payload is too large to store (estimated 18.42 MB, limit 15.0 MB, pre_persist)"
}

The public Transcript API still returns full segments (and words when stored). See Transcripts.

Job failure codes

When status is failed, read error (code + message). Full segment text is never on the Job object — use resultSummary / Transcripts API on success only. For how error relates to lastError, stage errors, and retries, see Jobs → Job failures & retries.

error.codeTypical cause
duration_exceededSource longer than the worker max duration.
unsupported_source_languageAuto-detect (or resolved) source language is not in the platform transcription allowlist.
transcript_too_largeTranscript BSON estimate or Mongo 16 MB limit on persist.
processing_failedEngine, download, or worker misconfiguration (missing API keys, network, etc.).

Inspect progress[] for stage-level failed events and nested error objects — especially for early download failures.