All docs
API reference
Hooks
List your hook library and trigger an on-demand refresh.
Hooks are short openers tagged by niche, language, and category. The system refreshes them daily on Starter+; this API also exposes a manual on-demand refresh trigger (Starter+, rate limited to 1/hour per organization).
GET
/v0/api/v1/hooksAPI key or sessionList hooks for your organization. Default sort: performance_score desc.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| page | query | integer | 1-indexed page (default 1). |
| limit | query | integer | Items per page, max 200 (default 50). |
| niche | query | string | Filter by niche. |
| language | query | string | ISO language code. |
| category | query | string | problem | curiosity | social_proof | listicle | contrarian | story. |
| status | query | string | APPROVED | PENDING | REJECTED. |
| q | query | string | Case-insensitive substring search on hook text. |
| sort | query | string | Pass "recent" to sort by createdAt desc instead of performance. |
Response
json
{
"success": true,
"data": [
{
"_id": "hk_01HQ...",
"organization_id": "org_01HQ...",
"text": "POV: you found the meditation app that actually clicks.",
"category": "curiosity",
"language": "en",
"niche": "meditation",
"source": "TIKTOK_TREND",
"status": "APPROVED",
"performance_score": 0.82,
"createdAt": "2026-05-12T03:00:00.000Z"
}
],
"page": 1,
"limit": 50,
"total": 137
}cURL
Terminalbash
curl "https://api.viralslides.app/v0/api/v1/hooks?niche=meditation&language=en&limit=20" \
-H "Authorization: Bearer vs_live_..."POST
/v0/api/v1/hooks/refresh-nowAPI key or sessionTrigger an immediate hook library refresh for one app (or all active apps if app_id is omitted). Asynchronous — returns 202 with the jobs that were started.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
| app_id | body | string | Optional — refresh hooks for this app only. If omitted, refreshes all ACTIVE apps. |
Request
Request bodyjson
{ "app_id": "app_01HQ..." }Response
202 Acceptedjson
{
"success": true,
"data": {
"jobs_started": 1,
"apps": [
{ "id": "app_01HQ...", "name": "Meditate Daily", "niche": "meditation", "language": "en" }
]
}
}cURL
Terminalbash
curl -X POST https://api.viralslides.app/v0/api/v1/hooks/refresh-now \
-H "Authorization: Bearer vs_live_..." \
-H "Content-Type: application/json" \
-d '{}'TypeScript / JS
Node.jstypescript
const res = await fetch("https://api.viralslides.app/v0/api/v1/hooks/refresh-now", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.VIRALSLIDES_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({}),
})
if (res.status === 429) {
const wait = res.headers.get("Retry-After")
console.log(`rate-limited; retry in ${wait}s`)
}Errors
| Status | Code | Description |
|---|---|---|
| 403 | PLAN_UPGRADE_REQUIRED | Free plan — upgrade to Starter+ to refresh hooks manually. |
| 404 | NO_ACTIVE_APPS | No ACTIVE apps to refresh (or specified app_id not found). |
| 429 | RATE_LIMITED | Already refreshed within the last hour. Check Retry-After header. |
Refresh-now is asynchronous
It returns 202 immediately and runs the Gemini/OpenAI calls in the background. Poll GET /hooks to see new entries appear (typically within 10–30 seconds).