POST/v1/search

Search

Search across visual scenes, speech, and on-screen text in one call. Returns ranked video segments with relevance scores, timestamps, and source links.

Try it

Copy and run. Replace YOUR_CERUL_API_KEY with your actual key.

search.sh

bash
curl "https://api.cerul.ai/v1/search" \
  -H "Authorization: Bearer YOUR_CERUL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "Sam Altman views on AI video generation"
  }'

With reranking: Add "ranking_mode": "rerank" to use LLM-based reranking for higher relevance. Uses the Jina Reranker by default.

Parameters

Only query is required. All other fields are optional.

NameTypeRequiredDescription
querystringYesNatural-language search query. Max 400 characters.
max_resultsintegerNoNumber of results to return. 1–50, default 10.
include_answerbooleanNoGenerate an AI summary grounded in the matched evidence. Default false. Costs 2 credits instead of 1.
ranking_modestringNo"embedding" (default) for vector similarity, or "rerank" for LLM-based reranking with higher relevance.
filtersobjectNoNarrow results by speaker, source, date, or duration. See Filters below.

Filters

Pass these inside the filters object. All are optional.

NameTypeDescription
speakerstringFilter by speaker name.
sourcestringFilter by content source (e.g. "youtube").
published_afterstringISO date (YYYY-MM-DD). Only return content published after this date.
min_durationintegerMinimum video duration in seconds.
max_durationintegerMaximum video duration in seconds.

with-filters.sh

bash
curl "https://api.cerul.ai/v1/search" \
  -H "Authorization: Bearer YOUR_CERUL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "AGI timeline discussion",
    "max_results": 5,
    "include_answer": true,
    "ranking_mode": "rerank",
    "filters": {
      "speaker": "Sam Altman",
      "published_after": "2024-01-01",
      "min_duration": 60,
      "max_duration": 7200,
      "source": "youtube"
    }
  }'

Response

FieldTypeDescription
resultsarrayArray of matched video segments.
results[].idstringUnique result identifier.
results[].scorenumberRelevance score, 0.0 to 1.0.
results[].rerank_scorenumber | nullReranking score when ranking_mode is set to rerank.
results[].urlstringCerul tracking URL — redirects to the source video.
results[].titlestringVideo title.
results[].snippetstringMatched transcript or visual description.
results[].transcriptstring | nullFull ASR transcript text for the matched segment. Null for visual-only units.
results[].thumbnail_urlstring | nullPreview image URL.
results[].keyframe_urlstring | nullRepresentative keyframe image when available.
results[].durationintegerVideo duration in seconds.
results[].sourcestringContent source (e.g. "youtube").
results[].speakerstring | nullSpeaker name, if detected.
results[].timestamp_startnumber | nullStart time in seconds.
results[].timestamp_endnumber | nullEnd time in seconds.
answerstring | nullAI-generated summary. Only present when include_answer is true.
credits_usedintegerCredits consumed by this request.
credits_remainingintegerRemaining spendable credits after this request.
request_idstringUnique request identifier in the form req_<24-hex-chars>.
200 OK

response.json

json
{
  "results": [
    {
      "id": "unit_hmtuvNfytjM_1223",
      "score": 0.93,
      "rerank_score": 0.97,
      "url": "https://cerul.ai/v/a8f3k2x",
      "title": "Sam Altman on AI video generation",
      "snippet": "Current AI video generation tools are improving quickly but still constrained by controllability.",
      "transcript": "Current AI video generation tools are improving quickly but still constrained by controllability, production reliability, and the ability to steer outputs precisely.",
      "thumbnail_url": "https://i.ytimg.com/vi/hmtuvNfytjM/hqdefault.jpg",
      "keyframe_url": "https://cdn.cerul.ai/frames/hmtuvNfytjM/f0123.jpg",
      "duration": 7200,
      "source": "youtube",
      "speaker": "Sam Altman",
      "timestamp_start": 1223.0,
      "timestamp_end": 1345.0
    }
  ],
  "answer": "Sam Altman frames current AI video generation tools as improving quickly but still constrained by controllability.",
  "credits_used": 2,
  "credits_remaining": 998,
  "request_id": "req_9f8c1d5b2a9f7d1a8c4e6b02"
}

Daily free

Today: 10 / 10 free searches reset every UTC day

Sign in to see your live remaining count here. The first 10 searches each day still cost 0 credits.

Errors

Every /v1 error response carries an error.code (coarse category) plus an optional error.subcode (fine-grained reason), a human-readable error.message, and a request_id that matches the x-request-id response header. Clients and agents should branch on error.subcode ?? error.code — this preserves backward compatibility for callers that only understand the coarse code.

error-envelope.json

json
{
  "error": {
    "code": "forbidden",
    "subcode": "insufficient_credits",
    "message": "Insufficient credits for this request",
    "request_id": "req_9f8c1d5b2a9f7d1a8c4e6b02"
  }
}
StatusCodeSubcodeDescription
400invalid_requestGeneric schema or request validation failure — fix the body and do not retry unchanged.
401unauthorizedmissing_authorizationNo Authorization header on /v1/*. Add Authorization: Bearer cerul_... and retry.
401unauthorizedinvalid_authorization_headerAuthorization header is not a Bearer token (wrong scheme or empty Bearer).
401unauthorizedmalformed_api_keyAPI key fails format validation. Check copy/paste and the cerul_ prefix.
401unauthorizedinvalid_api_keyKey format is valid but the key is unknown. Regenerate it in the dashboard.
403forbiddenapi_key_inactiveAPI key was revoked or deactivated. Regenerate or reactivate the key.
403forbiddenbilling_holdAccount is under billing review. Contact support; do not auto-retry.
403forbiddeninsufficient_creditsWallet balance is below request cost. Check GET /v1/usage and prompt for top-up.
404not_foundUnknown /v1/* path or resource.
422invalid_requestinvalid_imageSearch image could not be decoded, downloaded, or is unsupported. Text-only search still works.
429rate_limitedrate_limit_exceededPer-key rate limit exceeded. Honor Retry-After plus jitter before retrying.
500internal_errorUnhandled internal failure. Retry with bounded exponential backoff and include request_id if it repeats.

Only auto-retry rate_limit_exceeded, rate_limited, and internal_error. For auth, billing, and invalid-request failures, stop retrying and surface the problem. 429 responses include a Retry-After header in seconds.