Video OCR & Entity Extraction API
SightAPI provides high-throughput developer endpoints for running frame-by-frame text extraction, bounding box detection, and timecoded metadata tracking on video files.
Rate limits
Each API key has a token-bucket allowance of 20 requests per 10 seconds. Every authenticated response includes RateLimit-Limit, RateLimit-Remaining, and RateLimit-Reset. A 429 response also includes Retry-After; wait that many seconds before retrying.
Authentication
Every API request must include your secret API key in an Authorization header formatted as Bearer <prefix>.<secret>.
Authorization: Bearer prefix_1234.secret_5678Quickstart Workflow
4 Step PipelineCreate Input Asset & Get Presigned Upload URL
Post video metadata to initialize an asset record and obtain a signed upload target.
curl -X POST https://sightapi.work/api/v1/assets \
-H "Authorization: Bearer <prefix>.<secret>" \
-H "Content-Type: application/json" \
-d '{"filename":"sample.mp4","content_type":"video/mp4"}'Upload Video Payload
Upload raw video bytes directly to the returned presigned upload_url.
curl -X PUT "<upload_url>" --upload-file sample.mp4Choose and Dispatch a Video Operation
Select OCR, ENTITY_EXTRACTION, OCR_RENDER, or ENTITY_RENDER.
curl -X POST https://sightapi.work/api/v1/jobs \
-H "Authorization: Bearer <prefix>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"input_asset_id":"123e4567-e89b-12d3-a456-426614174000",
"operation":"ENTITY_RENDER",
"entities":["EMAIL","PERSON"],
"render":{"type":"redact","blur_strength":75},
"idempotency_key":"sample-upload-1"
}'Fetch Frame OCR & Bounding Box Output
JSON operations return only their requested tracks. Render operations return a hardware-encoded MP4.
curl -X GET https://sightapi.work/api/v1/jobs/<job_id>/result \
-H "Authorization: Bearer <prefix>.<secret>"Supported entity categories
The entities array accepts only the 10 uppercase, case-sensitive values below. It is required for ENTITY_EXTRACTION and ENTITY_RENDER, accepts 1–10 values, and must not be sent with either OCR operation. Slight OCR corruption may be repaired during classification, but the returned track remains aligned to the text detected in the video.
| Value | What it matches | Example | Not matched |
|---|---|---|---|
| PERSON | A specific person’s full or partial name. | Ada Lovelace | Generic roles such as “Admin” or “Manager” |
| COMPANY | A named business, brand, or commercial organization. | Acme Inc. | Generic phrases such as “the bank” |
| An email address in username@domain format. | ada@example.com | Usernames without a domain | |
| CURRENCY | A monetary amount with a symbol, ISO code, or clear financial context. | USD 1,250.00 | Unlabelled numbers |
| PASSWORD | A value explicitly identified by the surrounding text as a password. | Password: hunter2 | Unlabelled arbitrary strings |
| API_KEY | A high-entropy key, secret, or token explicitly identified as such. | API key: sk_live_… | Unlabelled IDs |
| DATE | A date, timestamp, or specific time value. | 2026-06-18 3:45 PM | Vague phrases such as “next week” |
| ADDRESS | A physical or postal address, including meaningful locality and postal information. | 123 Main St, New York, NY 10001 | Generic words such as “office” |
| PHONE | A telephone or mobile number in a recognizable format. | +91 98765 43210 | Unlabelled numeric identifiers |
| URL | A web address with a protocol, www prefix, or recognizable domain. | https://example.com/path | Ordinary text containing a dot |
Job request examples
Every job needs an uploaded input_asset_id. An optional idempotency_key (1–255 characters) safely identifies a create request for retry. The four valid request shapes are shown below.
OCR — return all text tracks as JSON
Do not include entities or render.
curl -X POST https://sightapi.work/api/v1/jobs \
-H "Authorization: Bearer <prefix>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"input_asset_id":"123e4567-e89b-12d3-a456-426614174000",
"operation":"OCR",
"idempotency_key":"video-42-ocr"
}'ENTITY_EXTRACTION — return selected entity tracks as JSON
Include one or more supported entity values. Do not include render.
curl -X POST https://sightapi.work/api/v1/jobs \
-H "Authorization: Bearer <prefix>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"input_asset_id":"123e4567-e89b-12d3-a456-426614174000",
"operation":"ENTITY_EXTRACTION",
"entities":["EMAIL","PHONE","API_KEY"]
}'OCR_RENDER — render every OCR track into an MP4
Include render and omit entities. Rectangle thickness is 1–20 pixels and defaults to 4 when omitted.
curl -X POST https://sightapi.work/api/v1/jobs \
-H "Authorization: Bearer <prefix>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"input_asset_id":"123e4567-e89b-12d3-a456-426614174000",
"operation":"OCR_RENDER",
"render":{"type":"rectangle","color":"#5B5FEF","thickness":4}
}'ENTITY_RENDER — render only selected entities into an MP4
Include both entities and render. Redaction blur strength is an integer from 10–100 and defaults to 50 when omitted.
curl -X POST https://sightapi.work/api/v1/jobs \
-H "Authorization: Bearer <prefix>.<secret>" \
-H "Content-Type: application/json" \
-d '{
"input_asset_id":"123e4567-e89b-12d3-a456-426614174000",
"operation":"ENTITY_RENDER",
"entities":["PERSON","EMAIL","PHONE"],
"render":{"type":"redact","blur_strength":75}
}'Endpoint reference
All six user endpoints require Bearer authentication. Select an endpoint for its complete request, response, and error contract.
Create an asset record and receive a signed upload URL for raw video payload.
Enqueue one of four GPU video operations for an uploaded asset.
List historic and active OCR processing jobs with status, frame progress, and credit charges.
Get details, progress stage, and metadata for a specific job by UUID. Failed jobs include a structured error with a stable code, human-readable message, and user/system classification.
Full referenceCancel a queued or dispatching job and release its reserved credits. Jobs already processing or in a terminal state return 409 job_not_cancellable. This does not delete job history or results.
Full referenceStream the requested JSON track data or the rendered video/mp4.
Full reference/api/v1/assets
Creates a private input-asset record and a presigned URL for uploading one video. The API does not receive the video bytes in this request: send them with a separate PUT to the returned upload_url, then pass the asset_id to Create a job.
| Field | Required | Description |
|---|---|---|
| filename | Yes | Non-empty string used to identify the upload. |
| content_type | No | A video/* MIME type or application/octet-stream. |
| size_bytes | No | File size hint. Values above 2 GB are rejected before an upload URL is issued. |
{
"asset_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "pending",
"upload_url": "https://storage.example.com/…",
"upload_method": "PUT"
}Upload the file body without the API authorization header: curl -X PUT "<upload_url>" --upload-file sample.mp4. The signed URL carries its own temporary authorization. A job created before the object is available returns 409 asset has not finished uploading.
/api/v1/jobs
Validates an uploaded asset, reserves credits, and dispatches one processing operation. New jobs return 201. Repeating a request with the same organization-scoped idempotency_key returns the original job with 200, allowing safe retries without duplicate work or charges.
| Field | Required | Rules |
|---|---|---|
| input_asset_id | Yes | UUID returned by Create an asset; it must belong to your organization. |
| operation | Yes | One of the four uppercase values in Operations and request shapes. |
| entities | Entity operations | 1–10 values from the supported categories; invalid on OCR-only operations. |
| render | Render operations | rectangle requires a #RRGGBB color and accepts thickness 1–20 (default 4). redact accepts blur strength 10–100 (default 50). |
| idempotency_key | No | 1–255 characters. Reuse only when retrying the same logical request. |
{
"job_id": "8db45a2a-5546-45b6-b438-c26b12b9fe2f",
"status": "dispatching",
"input_asset_id": "123e4567-e89b-12d3-a456-426614174000",
"operation": "ENTITY_EXTRACTION",
"options": { "entities": ["EMAIL", "PHONE"] },
"progress": 0,
"current_stage": null,
"reserved_credits": 14,
"charged_credits": null,
"created_at": "2026-07-29T10:30:00.000Z"
}/api/v1/jobs
Returns your organization's jobs in newest-first order. Use offset pagination for job history and the optional status filter for queues or completed work.
| Query | Default | Description |
|---|---|---|
| status | All | dispatching, processing, completed, failed, or cancelled; matching is case-insensitive. |
| limit | 25 | Integer from 1 through 200. |
| offset | 0 | Non-negative number of matching jobs to skip. |
curl "https://sightapi.work/api/v1/jobs?status=processing&limit=25&offset=0" \
-H "Authorization: Bearer <prefix>.<secret>"{
"items": [{ "job_id": "…", "status": "processing", "progress": 42 }],
"total": 31,
"limit": 25,
"offset": 0,
"has_more": true
}Each item uses the same complete job shape as Get a job. To request the next page, add the current limit to offset. A malformed filter or range returns 400.
/api/v1/jobs/{id}
Returns the current state of one job. Poll this endpoint until status is completed, failed, or cancelled, then use Download a result for completed jobs.
curl https://sightapi.work/api/v1/jobs/8db45a2a-5546-45b6-b438-c26b12b9fe2f \
-H "Authorization: Bearer <prefix>.<secret>"| Response field | Meaning |
|---|---|
| status, progress, current_stage | Lifecycle state, numeric progress, and the worker's current processing stage. |
| reserved_credits, charged_credits | Initial hold and final charge. The final value is null until charging completes. |
| processing_seconds, decoded_frames | Measured worker time and decoded frame count, available as processing advances or completes. |
| result | Small inline result metadata when available. Fetch the canonical output from the result endpoint. |
| error | For failed jobs: stable code, readable message, and user or system type. |
| created_at, started_at, completed_at | ISO 8601 timestamps; lifecycle timestamps remain null until their events occur. |
An invalid UUID returns 400. A missing job and a job owned by a different organization both return 404, preventing cross-tenant discovery.
Operations, rendering, and billing
OCR returns OCR tracks only. ENTITY_EXTRACTION returns boxes only for the requested entity categories. OCR_RENDER renders all OCR tracks, while ENTITY_RENDER renders only requested entities. Rectangle rendering accepts a #RRGGBB colour and optional thickness; redaction accepts a blur strength from 10–100.
Successful jobs cost 2 credits per second of measured GPU-worker processing time. Partial credits round up to the next whole credit; the job response reports both processing_seconds and charged_credits.
Failed jobs are never charged. Input errors such as a corrupt file or unsupported codec are returned immediately with error.type = "user". Transient worker failures are retried automatically; if all attempts fail, the terminal response uses error.type = "system". In both cases, reserved credits are released.
{
"job_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "failed",
"charged_credits": null,
"error": {
"code": "bad_codec",
"message": "The video uses a codec that is not supported.",
"type": "user"
}
}/api/v1/jobs/{id}
Cancels a job only while its status is queued, pending, or dispatching. Cancellation is atomic: if processing starts first, the request is rejected. A successful cancellation releases reserved credits and retains the job as an auditable cancelled record; no job data is hard-deleted.
curl -X DELETE https://sightapi.work/api/v1/jobs/123e4567-e89b-12d3-a456-426614174000 \
-H "Authorization: Bearer <prefix>.<secret>"{
"job_id": "123e4567-e89b-12d3-a456-426614174000",
"status": "cancelled",
"current_stage": "cancelled",
"reserved_credits": 14,
"charged_credits": null
}404 — not found
The job does not exist or belongs to another organization. The response does not reveal cross-tenant resource existence.
409 — job_not_cancellable
The job is already processing, completed, failed, or cancelled. The response includes its current status.
/api/v1/jobs/{id}/result
Downloads the canonical output for a completed job. The response type follows the operation chosen when the job was created: OCR and ENTITY_EXTRACTION return JSON; OCR_RENDER and ENTITY_RENDER stream an MP4.
| Operation | Content-Type | Output |
|---|---|---|
| OCR | application/json | All detected text tracks, timecodes, and bounding boxes. |
| ENTITY_EXTRACTION | application/json | Only tracks classified into the requested entity categories. |
| OCR_RENDER | video/mp4 | Source video with every OCR track rendered. |
| ENTITY_RENDER | video/mp4 | Source video with only selected entities rendered or redacted. |
curl https://sightapi.work/api/v1/jobs/<job_id>/result \
-H "Authorization: Bearer <prefix>.<secret>" \
-o result.jsoncurl https://sightapi.work/api/v1/jobs/<job_id>/result \
-H "Authorization: Bearer <prefix>.<secret>" \
-o result.mp4JSON responses omit internal worker metrics by default. Add ?verbose=true to include them for diagnostics. Responses use Cache-Control: private, max-age=3600; rendered videos also include an inline filename based on the job ID.
The path contains an invalid job UUID.
The job or its stored result cannot be found.
The job has not completed; poll job status first.