Docs

Godance is an OpenAI-compatible REST API. If you've shipped against the OpenAI SDK, you already know the request shape of every endpoint below, and chat is drop-in: same JSON, same streaming format. Image and video generation run as async jobs, and errors come back as RFC 7807 problem details; see OpenAI SDK compatibility.

Get to first call in three steps

  1. Create an account and mint an API key in Settings → API Keys (returned in plaintext once — save it).
  2. Top up with card, ACH, or SEPA (Stripe), or USDT (NOWPayments). Same balance, same API.
  3. Point your OpenAI SDK at https://api.godance.ai/v1 and start switching model values.

Endpoint reference

POST /v1/chat/completions

OpenAI's chat completions contract. Set "stream": true for server-sent events; otherwise the response is a single JSON object.

Non-streaming returns 200 with a chat.completion object (choices[].message, finish_reason, usage). Streaming returns text/event-stream: one chat.completion.chunk per event, then data: [DONE]. Other OpenAI parameters (tools, top_p, response_format, …) aren't supported and are ignored.

curl https://api.godance.ai/v1/chat/completions \
  -H "Authorization: Bearer $GODANCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [{"role": "user", "content": "Hello"}],
    "stream": true
  }'

POST /v1/images/generations

The request shape is OpenAI's. Every image model runs as an async job, so this endpoint always answers 202 Accepted with a job_id — it never returns image data inline. Poll GET /v1/jobs/{id} for the result, or pass webhook_url and receive a signed POST when the images are ready.

The full cost (per-image price × n) is reserved from your balance when the job is accepted and refunded automatically if generation fails. An insufficient balance returns 402.

curl https://api.godance.ai/v1/images/generations \
  -H "Authorization: Bearer $GODANCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "flux-2-pro",
    "prompt": "a lighthouse at dusk, watercolor",
    "n": 1,
    "webhook_url": "https://example.com/hooks/godance"
  }'
HTTP/1.1 202 Accepted

{
  "job_id": "6f1c0b9e-2d4a-4c3b-9a57-0e8d4b2f7c11",
  "status": "QUEUED",
  "poll_url": "/v1/jobs/6f1c0b9e-2d4a-4c3b-9a57-0e8d4b2f7c11"
}

POST /v1/videos/generations

Always async — video takes minutes, longer than an HTTP request should wait. The response is the same 202 + job_id body as for images; poll the job or pass webhook_url.

Cost is the model's per-second rate × seconds × n, reserved up front and refunded if generation fails.

GET /v1/jobs/{id}

Returns one async job. GET /v1/jobs lists all of your jobs, newest first. A job ID that isn't yours returns 404. Fields are camelCase:

CRUD /v1/keys

Send your key as Authorization: Bearer gd_live_…. A key calls the model API only: chat completions, image and video generations, jobs and usage. Everything else, these endpoints included, needs a signed-in session; a key gets 403 there. Create keys in the dashboard or with these endpoints:

An unknown, inactive or expired key returns 401. A key restricted to an IP allowlist returns 403 from any other address.

POST /v1/billing/topup

Usage is paid from a prepaid credit balance. A top-up returns a hosted checkout URL; the credit lands on your balance once the payment provider confirms the payment.

An amount outside the allowed range returns 400; the error detail states the range.

GET /v1/webhooks/secret

Image and video jobs submitted with a webhook_url get a JSON POST to that URL when they complete. Each account has one signing secret:

The delivery body carries:

Deliveries are sent once, on success, with a 10-second timeout and no retries. A failed job sends no webhook — if one doesn't arrive, poll GET /v1/jobs/{id}.

Webhook signature verification

Outbound webhooks carry an X-Godance-Signature header in Stripe format: t=<unix>,v1=<hex>[,v1=<hex>...]. Each v1 is HMAC-SHA256 of <t>.<raw body>, so verify against the raw request body before parsing it. During the 24-hour grace window after a secret rotation, two v1= entries are included — verify against your stored secret and accept on ANY match.

import hmac, hashlib

def verify(payload, header, secret):
    t = int(header.split(',')[0][2:])
    sigs = [p[3:] for p in header.split(',') if p.startswith('v1=')]
    expected = hmac.new(
        secret.encode(), f"{t}.{payload}".encode(),
        hashlib.sha256
    ).hexdigest()
    return any(hmac.compare_digest(expected, s) for s in sigs)

OpenAI SDK compatibility

Point the OpenAI SDK at https://api.godance.ai/v1 and use a Godance key as the API key.

Questions? Email us.