API Reference
API Reference
Two endpoints: search videos and check usage. Both require a Bearer API key and return JSON responses.
Base URL
https://api.cerul.ai
All public requests share the same API origin.
Formats
JSON request + response
Authenticated routes are JSON-first with stable envelopes.
Auth
Bearer key
Dashboard sessions are separate from the public API contract.
Search videos
Search across visual scenes, speech, and on-screen text in one call. Returns ranked video segments with relevance scores, timestamps, and source links.
Authentication
Requires a Cerul API key in the Authorization header.
Request contract
Fields below describe the exact public contract. Omit optional values instead of sending empty placeholders.
Request parameters
Inputs accepted by this route
| Name | Type | Required | Description |
|---|---|---|---|
| query | string | Required | Natural-language search query (max 400 characters). |
| max_results | integer | Optional | Number of results to return, 1–50. Default: 10. |
| ranking_mode | string | Optional | "embedding" (default) for vector similarity, or "rerank" for LLM-based reranking. |
| include_answer | boolean | Optional | Generate an AI summary grounded in the matched evidence. Default: false. Costs 2 credits instead of 1. |
| filters | object | Optional | Filter results by speaker, source, published_after (YYYY-MM-DD), min_duration, or max_duration (seconds). |
Request examples
Run the endpoint from your stack
search.sh
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 tools",
"max_results": 5,
"ranking_mode": "rerank",
"include_answer": true,
"filters": {
"speaker": "Sam Altman",
"published_after": "2024-01-01"
}
}'search.py
import requests
response = requests.post(
"https://api.cerul.ai/v1/search",
headers={
"Authorization": "Bearer YOUR_CERUL_API_KEY",
"Content-Type": "application/json",
},
json={
"query": "Sam Altman views on AI video generation tools",
"max_results": 5,
"ranking_mode": "rerank",
"include_answer": True,
"filters": {
"speaker": "Sam Altman",
"published_after": "2024-01-01",
},
},
)
print(response.json())search.js
const response = await fetch("https://api.cerul.ai/v1/search", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_CERUL_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
query: "Sam Altman views on AI video generation tools",
max_results: 5,
ranking_mode: "rerank",
include_answer: true,
filters: {
speaker: "Sam Altman",
published_after: "2024-01-01",
},
}),
});
const data = await response.json();
console.log(data);Response schema
response-schema.json
{
"results": [
{
"id": "string",
"score": "number (0.0–1.0)",
"rerank_score": "number | null",
"url": "string (tracking URL → redirects to source)",
"title": "string",
"snippet": "string",
"transcript": "string | null",
"thumbnail_url": "string | null",
"keyframe_url": "string | null",
"duration": "integer",
"source": "string",
"speaker": "string | null",
"timestamp_start": "number | null",
"timestamp_end": "number | null"
}
],
"answer": "string | null",
"credits_used": "integer",
"credits_remaining": "integer",
"request_id": "string"
}Response example
200 OKresponse-example.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 and production reliability.",
"credits_used": 2,
"credits_remaining": 998,
"request_id": "req_9f8c1d5b2a9f7d1a8c4e6b02"
}Check usage
Returns your current plan tier, billing period, spendable wallet, daily free allowance, and rate limit.
Authentication
Requires a Cerul API key. Use this to monitor usage before scaling traffic.
Request contract
This route does not accept request body fields or query parameters in the public contract.
Request parameters
Inputs accepted by this route
No parameters are required for this endpoint.
Request examples
Run the endpoint from your stack
usage.sh
curl "https://api.cerul.ai/v1/usage" \
-H "Authorization: Bearer YOUR_CERUL_API_KEY"usage.py
import requests
response = requests.get(
"https://api.cerul.ai/v1/usage",
headers={"Authorization": "Bearer YOUR_CERUL_API_KEY"},
)
print(response.json())usage.js
const response = await fetch("https://api.cerul.ai/v1/usage", {
headers: {
"Authorization": "Bearer YOUR_CERUL_API_KEY",
},
});
const data = await response.json();
console.log(data);Response schema
response-schema.json
{
"tier": "string",
"plan_code": "string",
"period_start": "YYYY-MM-DD",
"period_end": "YYYY-MM-DD",
"credits_limit": "integer",
"credits_used": "integer",
"credits_remaining": "integer",
"wallet_balance": "integer",
"credit_breakdown": {
"included_remaining": "integer",
"bonus_remaining": "integer",
"paid_remaining": "integer"
},
"expiring_credits": [
{
"grant_type": "string",
"credits": "integer",
"expires_at": "ISO-8601 datetime"
}
],
"billing_hold": "boolean",
"daily_free_remaining": "integer",
"daily_free_limit": "integer",
"rate_limit_per_sec": "integer",
"api_keys_active": "integer"
}Response example
200 OKresponse-example.json
{
"tier": "free",
"plan_code": "free",
"period_start": "2026-03-01",
"period_end": "2026-03-31",
"credits_limit": 0,
"credits_used": 18,
"credits_remaining": 82,
"wallet_balance": 82,
"credit_breakdown": {
"included_remaining": 0,
"bonus_remaining": 82,
"paid_remaining": 0
},
"expiring_credits": [],
"billing_hold": false,
"daily_free_remaining": 7,
"daily_free_limit": 10,
"rate_limit_per_sec": 1,
"api_keys_active": 1
}