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
status | Meaning |
|---|---|
pending | References are still downloading, or the sheet has not started. |
generating_sheet | The character sheet is in flight. |
generating_outfits | The sheet is done; outfits are still filling in. Only reachable with include_outfits: true. |
ready | Everything this character will produce has reached a terminal state: the sheet alone, or the sheet and all five outfits. |
failed | The 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.
slug | label |
|---|---|
casual-everyday | Casual everyday |
business-formal | Business formal |
athleisure | Athleisure |
evening-formal | Evening formal |
outerwear | Cold-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=0Returns 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 .| Param | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Max items to return |
offset | integer | 0 | Pagination 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
| Status | Meaning |
|---|---|
401 | Missing or invalid API key |
404 | Unknown character id, or one belonging to another organization |