HookGeniusAPI

HookGenius API

Turn an idea into a finished title, full lyrics, and a producer-grade style prompt with one HTTP call — the same engine the HookGenius app runs on. Pair it with any audio generator (Suno, Udio, your own) for the sound.

Base URL  https://api.hookgenius.app

Introduction

The API exposes a single capability: songwriting. You send an idea (plus any creative controls), and you get back a complete song spec — title, lyrics with section tags and vocal direction, and a style_prompt tuned to render correctly in a music model. Generation runs the full HookGenius pipeline (best-of-N drafting → critic selection → producer refinement), so it takes ~30–60 seconds per call. The API is therefore asynchronous: you create a job, then receive the result by polling, long-poll, or webhook.

Authentication

Authenticate every request with your secret API key as a bearer token. Keys come in two modes: hg_test_… (free sandbox) and hg_live_… (real generations, billed). Keys are shown once at creation and stored hashed — treat them like a password and never expose one in client-side code.

Authorization: Bearer hg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Keep your key server-side. All generation happens on our infrastructure — your key only ever travels from your backend to ours over HTTPS. If a key is exposed, revoke it from your console and issue a new one; revocation is instant.

Quickstart

Create a generation and wait up to 60 seconds for the result inline using ?wait:

# 1 — create (and wait for) a generation
curl https://api.hookgenius.app/v1/generations?wait=60 \
  -H "Authorization: Bearer hg_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "idea": "a triumphant late-night drive home after quitting a dead-end job",
    "genre": "synthwave",
    "vocal": { "gender": "male" }
  }'
# → 200 (completed within the wait window)
{
  "id": "gen_8f2c…",
  "object": "generation",
  "status": "completed",
  "output": {
    "title": "Last Punch Out",
    "lyrics": "[Verse 1]\nBadge on the break room table…",
    "style_prompt": "synthwave outrun, 95 BPM, warm analog polysynth arpeggios, male warm baritone…",
    "languages": ["English"]
  },
  "usage": { "credits": 1 }
}

Then feed output.lyrics and output.style_prompt straight into your audio model's custom/lyrics mode.

Sandbox / test mode

A hg_test_ key returns a realistic sample response instantly — no real generation runs, and it never costs a credit. Use it to wire up auth, request shape, polling/webhooks, and error handling before you spend anything. Sandbox responses include "sandbox": true in the output and titles suffixed (sample) so you never confuse them with live output.

Build your entire integration against a test key for free. Switch the key to hg_live_ and the exact same code produces real songs.

Create a generation

POST /v1/generations

Creates a generation job. Returns 202 with a queued job immediately, or — if you pass ?wait=N and it finishes within N seconds (max 90) — 200 with the completed result. Billing is debit-before-generate: one credit is held when the job is created and automatically refunded if the generation fails. Test keys never charge.

Query parameters

ParamTypeDescription
waitintegerOptional. Long-poll up to N seconds (capped at 90) for the job to finish before responding. Omit to return 202 immediately and poll separately.

Headers

HeaderDescription
AuthorizationrequiredBearer <key>
Idempotency-KeyOptional. A unique string you generate; replaying the same key + body returns the original job instead of creating (or charging) a new one. See Idempotency.

The async model

Because a generation takes ~30–60 seconds, choose one of three ways to receive the result:

1 · Long-poll (simplest)

POST /v1/generations?wait=60
# blocks up to 60s,
# returns completed result

2 · Poll

POST /v1/generations  → 202 {id}
GET  /v1/generations/{id}
# repeat every ~3s until
# status: completed
Webhooks (fire-and-forget delivery to your endpoint) are on the v1 roadmap. Until then, long-poll is the simplest path and poll is the most robust for high volume.

Retrieve a generation

GET /v1/generations/{id}

Returns the current state of a generation. status is one of queued, processing, completed, or failed. Once completed, output is populated.

curl https://api.hookgenius.app/v1/generations/gen_8f2c… \
  -H "Authorization: Bearer hg_live_…"

Request field reference

Every field below is accepted on POST /v1/generations and verified end-to-end against the live engine. Only idea is required; everything else sharpens the result.

FieldTypeDescription
idearequiredstringThe concept, theme, or brief for the song. Up to 2000 chars.
genrestringPrimary genre, e.g. "synthwave", "arena rock", "folk".
sub_genrestringRefines the genre, e.g. "outrun".
artist_influencesstring[]Artists to absorb the stylistic feel of. Influence is internalized, never named in the output.
song_references{title, artist}[]Reference tracks to anchor the vibe.
vocalobject{ "gender": "male" | "female" | "any", "description": "warm weary baritone" }. Both optional.
languagesstring[]Languages to write in. Defaults to ["English"].
required_keywordsstring[] | stringWords or phrases the lyrics must include.
exclusionsstring[]Themes, words, or imagery to avoid (e.g. "religious imagery").
locked_lyricsobject{ "text": "…", "mode": "exact" | "enhance" | "inspire" }. Bring your own lyrics: exact preserves them verbatim and writes only the surrounding structure; enhance polishes them; inspire uses them as a seed.
titlestringOptional fixed title. Omit to have one written for you.

Response shape

{
  "id": "gen_8f2c…",
  "object": "generation",
  "status": "completed",        // queued | processing | completed | failed
  "created_at": 1782851678,        // unix seconds
  "completed_at": 1782851731,
  "output": {
    "title": "…",
    "lyrics": "…",            // section tags + vocal direction included
    "style_prompt": "…",      // comma-separated, ready for a music model
    "languages": ["English"]
  },
  "usage": { "credits": 1 },
  "error": null
}

Usage & balance

GET /v1/usage

Returns your remaining credit balance, mode, rate limit, calls in the last 60s, and recent generations.

{
  "credits_remaining": 948,
  "mode": "live",
  "rate_limit_per_min": 30,
  "used_last_60s": 2,
  "recent": [ { "id": "gen_…", "status": "completed", "created_at": 1782851678 } ]
}

Key info

GET /v1/me

Returns metadata about the calling key, with the key value masked.

{ "id": "key_…", "key": "hg_live_…a1b2", "mode": "live", "credits_remaining": 948 }

Errors

Errors use standard HTTP status codes and a consistent JSON envelope:

{ "error": { "type": "insufficient_credits", "code": "no_credits", "message": "Insufficient credits. Top up your balance to continue." } }
StatustypeWhen
400invalid_request_errorMalformed JSON or invalid/missing fields (param names the field).
401authentication_errorMissing or invalid API key.
402insufficient_creditsBalance is zero. Top up to resume — no calls are charged while empty.
403permission_errorKey revoked.
404invalid_request_errorNo generation with that id under your key.
429rate_limit_errorPer-key rate limit exceeded. Respect the Retry-After header.

Rate limits

Each key has a per-minute rate limit (default 30 requests/min; raised on request for higher-volume accounts). Exceeding it returns 429 with a Retry-After header. Generation latency, not the rate limit, is usually the throughput ceiling — design around the async model.

Idempotency

Safely retry create requests without risk of duplicate work or double-charging by sending a unique Idempotency-Key header. If we've already seen that key for your account, we return the original generation instead of creating a new one. Use a fresh UUID per logical generation.

curl https://api.hookgenius.app/v1/generations \
  -H "Authorization: Bearer hg_live_…" \
  -H "Idempotency-Key: 9f1c2e7a-…" \
  -H "Content-Type: application/json" \
  -d '{ "idea": "…" }'

Pricing & credits

One credit = one finished song. Credits are prepaid: buy them up front, and when your balance reaches zero the API pauses (returns 402) until you top up — no overage, no surprise bills.

TierPrice / generation
Standard$0.99
Volume — 1,000+ credits prepaid$0.79
Scale — 10,000+ credits prepaid$0.69
Sandbox / test modeFree

Failed generations are never charged. Manage credits and keys from your console.