API docs · Get started
Quickstart
Process your first video in a few minutes. Get a key, create a job from a URL or a local file, wait for it, and read the transcript and scenes.
1. Get a key
During the public beta, request access by email first. Once your account is on, buy a credit pack on the API keys page (packs start at $10). Polar, our billing provider, issues your key with the purchase; it starts with fq_live_. Put it in an environment variable on the machine that will call the API:
export FRAMEQUERY_API_KEY="fq_live_..."Check it works. GET /quota returns your balance:
curl https://api.framequery.com/v1/api/quota \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY"{
"data": {
"api": {
"available": true,
"balanceCents": 1000,
"heldCents": 0,
"availableCents": 1000,
"payAsYouGo": false,
"monthUsageSeconds": 0,
"tier": "standard",
"volumeThresholdSeconds": 1800000
}
},
"requestId": "4b0c2f8e9a1d4c67"
}2. Install an SDK (optional)
Everything below works with plain HTTP. The SDKs add uploads, polling, retries and typed results:
# Nothing to install. The examples use curl and jq.3. Process a video from a URL
Any public http(s) URL works, including presigned S3, R2, B2 or Google Cloud Storage links.
curl -X POST https://api.framequery.com/v1/api/jobs/from-url \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"url": "https://example.com/interview.mp4",
"processingMode": "all",
"metadata": { "assetId": "A003_C008" }
}'The curl call returns the full Job object straight away, in state queued:
{
"data": {
"jobId": "0b5e6c1e-6f43-4a0e-9d4c-2f7f3c1b9a10",
"state": "queued",
"processingMode": "all",
"format": { "tier": "standard", "extension": "mp4" },
"stages": {
"ingest": { "status": "pending" },
"vision": { "status": "pending" },
"transcript": { "status": "pending" }
},
"metadata": { "assetId": "A003_C008" },
"links": {
"self": "https://api.framequery.com/v1/api/jobs/0b5e6c1e-6f43-4a0e-9d4c-2f7f3c1b9a10",
"transcript": "https://api.framequery.com/v1/api/jobs/0b5e6c1e-6f43-4a0e-9d4c-2f7f3c1b9a10/transcript",
"scenes": "https://api.framequery.com/v1/api/jobs/0b5e6c1e-6f43-4a0e-9d4c-2f7f3c1b9a10/scenes",
"cancel": "https://api.framequery.com/v1/api/jobs/0b5e6c1e-6f43-4a0e-9d4c-2f7f3c1b9a10/cancel"
}
},
"requestId": "9f2a61c0b7e34d18"
}4. Or upload a local file
POST /jobs creates the job and returns a signed upload URL. Upload straight to it; the bytes never pass through our API servers. Send every header in uploadHeaders exactly as given (they are part of the signature) and do not send your API key to the upload URL.
FILE=interview.mp4
RESPONSE=$(curl -sS -X POST https://api.framequery.com/v1/api/jobs \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d "{\"fileName\": \"$FILE\", \"fileSizeBytes\": $(wc -c < "$FILE")}")
JOB_ID=$(echo "$RESPONSE" | jq -r .data.jobId)
UPLOAD_URL=$(echo "$RESPONSE" | jq -r .data.uploadUrl)
# Turn uploadHeaders into -H arguments and PUT the file.
HEADERS=()
while IFS= read -r h; do HEADERS+=(-H "$h"); done \
< <(echo "$RESPONSE" | jq -r '.data.uploadHeaders | to_entries[] | "\(.key): \(.value)"')
curl -sS -X PUT "$UPLOAD_URL" "${HEADERS[@]}" --upload-file "$FILE"Processing starts as soon as the upload completes. For files over a few hundred megabytes use the resumable upload described in Jobs; the SDKs switch to it automatically above 32 MiB.
5. Wait for the job
Poll the job and branch on state. include=none keeps the response small.
curl "https://api.framequery.com/v1/api/jobs/$JOB_ID?include=none" \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY"The job moves from queued (or awaiting_upload) to processing, then to one terminal state: completed, failed, cancelled or expired. Rather than polling, you can pass a callbackUrl when you create the job and receive a signed webhook.
6. Read the results
# Transcript as JSON, then as an SRT file
curl "https://api.framequery.com/v1/api/jobs/$JOB_ID/transcript" \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY"
curl "https://api.framequery.com/v1/api/jobs/$JOB_ID/transcript?format=srt" \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY" -o interview.srt
# Scenes with captions
curl "https://api.framequery.com/v1/api/jobs/$JOB_ID/scenes" \
-H "Authorization: Bearer $FRAMEQUERY_API_KEY"Field-by-field shapes are in Results.
Next steps
- Webhooks: get notified instead of polling, and verify signatures.
- Pricing and billing: what a job costs, and how to estimate it before you send it.
- Errors: every error code, and which ones to retry.
- SDKs: Python and TypeScript reference.