GoodTake AI Docs
Character API

Retrieve & List

Poll a character's status, sheet and outfits, or list your organization's characters

Poll a character

GET /v1/character/{id}
curl -s "https://api.goodtake.ai/v1/character/$ID" \
  -H "Authorization: Bearer $GOODTAKE_API_KEY" | jq .

Response

{
  "id": "9f1c8400-e29b-41d4-a716-446655440021",
  "name": "Ava — spring campaign",
  "status": "generating_outfits",
  "model": "dola-seedream-5-0-pro-260628",
  "include_outfits": true,
  "references": { "provided": 12, "stored": 12, "sent_to_model": 10 },
  "sheet": {
    "generation_id": "3ab2c400-e29b-41d4-a716-446655440022",
    "status": "completed",
    "image": {
      "url": "https://storage.googleapis.com/...signed...",
      "width": 2304,
      "height": 1728
    },
    "completed_at": "2026-09-04T13:20:11Z"
  },
  "outfits": [
    {
      "slug": "casual-everyday",
      "label": "Casual everyday",
      "generation_id": "7c40...",
      "status": "completed",
      "image": { "url": "https://...", "width": 1728, "height": 2304 }
    },
    {
      "slug": "business-formal",
      "label": "Business formal",
      "generation_id": "8d51...",
      "status": "processing"
    },
    { "slug": "athleisure", "label": "Athleisure", "status": "pending" },
    {
      "slug": "evening-formal",
      "label": "Evening formal",
      "status": "pending"
    },
    {
      "slug": "outerwear",
      "label": "Cold-weather outerwear",
      "status": "pending"
    }
  ],
  "estimated_cost": 36,
  "cost_credits": 10,
  "warnings": [
    {
      "code": "references_clamped",
      "message": "12 reference images stored, 10 sent to the model (model maximum)"
    }
  ],
  "created_at": "2026-09-04T13:18:02Z"
}

Statuses

statusMeaning
pendingReferences are still downloading, or the sheet has not started.
generating_sheetThe character sheet is in flight.
generating_outfitsThe sheet is done; outfits are still filling in. Only reachable with include_outfits: true.
readyEverything this character will produce has reached a terminal state: the sheet alone, or the sheet and all five outfits.
failedThe sheet did not produce an image.

ready does not mean everything succeeded. An individual outfit can fail while the character is ready — check each outfit's own status. A character that is 5-of-6 usable is worth keeping, so the whole thing is not reported as failed for one bad variant.

Poll every 3–5 seconds. A sheet-only character typically takes 20–60 seconds; a full one takes 1–3 minutes — the sheet first, then the five outfits in parallel.

The outfit set

Opt in with include_outfits: true at create. Five variants, fixed, always returned in this order with a stable slug — even before their generation exists, so you can render a fixed grid without it reflowing on every poll.

sluglabel
casual-everydayCasual everyday
business-formalBusiness formal
athleisureAthleisure
evening-formalEvening formal
outerwearCold-weather outerwear

Each outfit is generated from the finished character sheet, not from your original photos. That is what keeps the five variants consistent with each other: they all anchor on one canonical image rather than on a dozen inconsistent snapshots.

For a sheet-only character, outfits is [] and stays []. Branch on include_outfits: false rather than waiting for an array that will never fill.

Image URLs expire

image.url is a signed URL valid for 7 days. Re-fetch the character to get a fresh one — the endpoint re-signs anything close to expiry on read. Do not cache these URLs; cache the id.

List characters

GET /v1/character?limit=20&offset=0

Returns your organization's characters, newest first, with derived statuses but without image payloads.

curl -s "https://api.goodtake.ai/v1/character?limit=10" \
  -H "Authorization: Bearer $GOODTAKE_API_KEY" | jq .
ParamTypeDefaultDescription
limitinteger20Max items to return
offsetinteger0Pagination offset

Full polling example

KEY="gt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
BASE="https://api.goodtake.ai/v1"

# 1. Create
ID=$(curl -s -X POST "$BASE/character" \
  -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"name":"Ava","image_urls":["https://example.com/1.jpg","https://example.com/2.jpg","https://example.com/3.jpg","https://example.com/4.jpg"],"include_outfits":true}' \
  | jq -r .id)

# 2. Poll until terminal
while :; do
  BODY=$(curl -s "$BASE/character/$ID" -H "Authorization: Bearer $KEY")
  STATUS=$(echo "$BODY" | jq -r .status)
  echo "status: $STATUS"
  [ "$STATUS" = "ready" ] || [ "$STATUS" = "failed" ] && break
  sleep 4
done

# 3. Collect the six URLs
echo "$BODY" | jq -r '[.sheet.image.url] + [.outfits[].image.url // empty] | .[]'

Errors

StatusMeaning
401Missing or invalid API key
404Unknown character id, or one belonging to another organization