Avatars
Generate draft AI avatars from typed traits, then approve or rename them. Drafts never enter the library without human approval; the user manages or discards unwanted drafts from the dashboard.
create_avatar
WRITEREST: POST /api/v2/avatars
Generate draft avatar(s) from appearance traits + an optional scene prompt. Returns drafts that are NOT saved to the library; the user must approve them. Any traits you omit are randomized. Costs credits per image; the result reports creditsSpent and creditsRemaining. Drafts are billed once at creation, never expire, and cost nothing to keep unapproved. Each draft carries dashboardUrl, the dashboard door to that draft.
{
"type": "object",
"properties": {
"workspace": {
"type": "string",
"minLength": 1,
"description": "Required write target: a workspace slug or id from list_workspaces. Writes never inherit the connection default."
},
"traits": {
"description": "Appearance traits. Any you omit are randomized (gender-aware).",
"type": "object",
"properties": {
"gender": {
"type": "string",
"enum": [
"Female",
"Male"
]
},
"ageBand": {
"type": "string",
"enum": [
"18-19",
"20s",
"30s",
"40s",
"50s",
"60s",
"70+"
]
},
"heritage": {
"type": "string",
"enum": [
"South Asian",
"East Asian",
"Black",
"White",
"Latino",
"Middle Eastern",
"Mixed"
]
},
"faceShape": {
"type": "string",
"enum": [
"Oval",
"Round",
"Heart",
"Square",
"Angular"
]
},
"skinTone": {
"type": "string",
"enum": [
"Porcelain",
"Fair",
"Light Medium",
"Medium",
"Olive",
"Tan",
"Deep"
]
},
"skinTexture": {
"type": "string",
"enum": [
"Airbrushed clean",
"Smooth natural",
"Soft matte",
"Freckled",
"Textured pores",
"Weathered rugged"
]
},
"hairColor": {
"type": "string",
"enum": [
"Jet Black",
"Black",
"Dark Brown",
"Medium Brown",
"Light Brown",
"Auburn",
"Blonde",
"Platinum Blonde",
"Copper Red",
"Salt & Pepper",
"Gray",
"Silver",
"White"
]
},
"hairStyle": {
"type": "string",
"enum": [
"Buzz cut",
"Crew cut",
"Fade",
"Textured crop",
"Short side part",
"Slicked back",
"Quiff",
"Natural short",
"Bob cut",
"Layered cut",
"Straight & sleek",
"Soft waves",
"Beach waves",
"Loose curls",
"Tight curls",
"Soft bangs",
"Center part",
"Side part",
"Ponytail",
"Sleek bun",
"Long & flowing",
"Messy tousled"
]
},
"eyeColor": {
"type": "string",
"enum": [
"Dark Brown",
"Brown",
"Hazel",
"Green",
"Blue",
"Gray",
"Amber",
"Gray-Blue"
]
},
"bodyBuild": {
"type": "string",
"enum": [
"Slim",
"Athletic",
"Average",
"Muscular",
"Broad",
"Curvy",
"Petite",
"Plus-size"
]
},
"facialHair": {
"type": "string",
"enum": [
"Clean shaven",
"Stubble",
"Short beard",
"Full beard",
"Goatee",
"Mustache"
]
},
"makeupStyle": {
"type": "string",
"enum": [
"No makeup",
"Natural / minimal",
"Soft glam",
"Bold glam",
"Smoky eye",
"Dewy fresh"
]
},
"bustSize": {
"type": "string",
"enum": [
"Petite",
"Small",
"Medium",
"Large",
"Very Large"
]
},
"outfitStyle": {
"type": "string",
"enum": [
"Casual t-shirt",
"Button-down shirt",
"Henley shirt",
"Polo shirt",
"Hoodie",
"Sweater",
"Denim jacket",
"Leather jacket",
"Bomber jacket",
"Suit jacket",
"Tank top",
"Flannel shirt",
"Crop top",
"Off-shoulder top",
"Tube top",
"Lace camisole",
"Halter top",
"Blouse",
"Bodysuit",
"Corset top",
"Sundress",
"Wrap top",
"Cardigan",
"Spaghetti strap top",
"Bandeau top",
"Blazer",
"Kurta",
"Sari",
"Sherwani",
"Hijab with modest outfit"
]
}
}
},
"notes": {
"description": "Free-text scene / pose / mood. Anything that is NOT a fixed trait. Scene wishes are best effort, not guaranteed: view the returned image before presenting it.",
"type": "string",
"maxLength": 2000
},
"count": {
"description": "How many draft variations to generate (default 1). Every draft in a call shares this ONE trait spec; count gives look variations of the same persona, not distinct people. For distinct personas, make one call per persona.",
"type": "integer",
"minimum": 1,
"maximum": 4
},
"names": {
"description": "A name for each draft, index-aligned with count. YOU (the AI) should pick trait-appropriate names; omit to let the server auto-name. Fewer names than count is fine: the remaining drafts get server-generated names.",
"maxItems": 4,
"type": "array",
"items": {
"type": "string",
"maxLength": 100
}
},
"model": {
"description": "Image model (default gemini_flash). Higher tiers cost more credits.",
"type": "string",
"enum": [
"gemini_flash_lite",
"gemini_flash",
"gemini_pro",
"gpt_low",
"gpt_medium",
"gpt_high"
]
},
"idempotencyKey": {
"description": "A stable key to reuse if you retry this exact request; a repeat with the same key is NOT charged again.",
"type": "string",
"maxLength": 200
}
},
"required": [
"workspace"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}{
"success": true,
"data": {
"avatars": [
{
"avatarId": "avt_9f8e7d6c5b4a3210",
"name": "Maya",
"imageUrl": "https://cdn.ghostfeed.ai/avatars/drafts/avt_9f8e7d6c5b4a3210.png",
"status": "draft",
"dashboardUrl": "https://ghostfeed.ai/w/client-a/avatar?create=1&draft=avt_9f8e7d6c5b4a3210&ref=agent"
}
],
"traits": {
"gender": "Female",
"ageBand": "20s",
"heritage": "South Asian",
"faceShape": "Oval",
"skinTone": "Medium",
"skinTexture": "Smooth",
"hairColor": "Black",
"hairStyle": "Long Wavy",
"eyeColor": "Brown",
"bodyBuild": "Slim",
"outfitStyle": "Casual"
},
"creditsSpent": 2,
"creditsRemaining": 45,
"total": 1,
"page": 1,
"pages": 1,
"nextSteps": "1 draft avatar created, NOT yet in the library. Show them to the user and call approve_avatar with the avatarId(s) they want to keep. You cannot delete drafts; the user manages or discards the rest from the dashboard. Each draft dashboardUrl opens it in the dashboard. Report the spend: 2 credits spent, 45 remaining."
}
}approve_avatar
WRITEIDEMPOTENTREST: POST /api/v2/avatars/:id/approve
Approve a draft avatar by its avatarId, promoting it into the library (optionally rename). Only approve drafts the USER chose to keep. Returns dashboardUrl for the saved avatar.
{
"type": "object",
"properties": {
"avatarId": {
"type": "string",
"description": "The avatarId of the draft to approve (from create_avatar)."
},
"workspace": {
"type": "string",
"minLength": 1,
"description": "Required write target: a workspace slug or id from list_workspaces. Writes never inherit the connection default."
}
},
"required": [
"avatarId",
"workspace"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}{
"success": true,
"data": {
"avatarId": "avt_9f8e7d6c5b4a3210",
"name": "Maya",
"thumbnailUrl": "https://cdn.ghostfeed.ai/avatars/saved/avt_9f8e7d6c5b4a3210/thumb.png",
"status": "saved",
"dashboardUrl": "https://ghostfeed.ai/w/client-a/avatar?selected=avt_9f8e7d6c5b4a3210&ref=agent",
"nextSteps": "Approved and saved to the library. Open it: https://ghostfeed.ai/w/client-a/avatar?selected=avt_9f8e7d6c5b4a3210&ref=agent"
}
}rename_avatar
WRITEIDEMPOTENTREST: PATCH /api/v2/avatars/:id
Rename an avatar (draft or saved) by its avatarId. Pure rename: does NOT save/approve a draft or change anything else.
{
"type": "object",
"properties": {
"avatarId": {
"type": "string",
"description": "The avatarId to rename (draft OR saved)."
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "The new name."
},
"workspace": {
"type": "string",
"minLength": 1,
"description": "Required write target: a workspace slug or id from list_workspaces. Writes never inherit the connection default."
}
},
"required": [
"avatarId",
"name",
"workspace"
],
"$schema": "http://json-schema.org/draft-07/schema#"
}{
"success": true,
"data": {
"avatarId": "avt_1a2b3c4d5e6f7081",
"name": "Priya V2",
"status": "saved",
"dashboardUrl": "https://ghostfeed.ai/w/client-a/avatar?selected=avt_1a2b3c4d5e6f7081&ref=agent",
"nextSteps": "Renamed."
}
}list_avatars
READREST: GET /api/v2/avatars
List SAVED (library) avatars in the active workspace: id, name, thumbnail. Use this to find an avatarId for rename_avatar or content generation. Unapproved drafts are separate (list_draft_avatars).
{
"type": "object",
"properties": {
"page": {
"description": "Page number (default 1).",
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"limit": {
"description": "Per page (max 100). Each tool documents its own default.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"workspace": {
"description": "Target workspace: a slug, id, or exact name from list_workspaces. Omit to use this connection's default workspace. Must be inside the credential's grant and your current access; overrides the connection-level X-Workspace-Id header.",
"type": "string"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}{
"success": true,
"data": {
"workspace": {
"id": "6a18c36ee586c7e44e4ece67",
"name": "Client A",
"slug": "client-a"
},
"avatars": [
{
"avatarId": "avt_1a2b3c4d5e6f7081",
"name": "Priya",
"imageUrl": "https://cdn.ghostfeed.ai/avatars/saved/avt_1a2b3c4d5e6f7081/thumb.png",
"imageCount": 6,
"gender": "Female",
"creationMethod": "ai_generated",
"createdBy": "64f1c2a1b2c3d4e5f6071829",
"createdAt": "2026-06-01T08:30:00.000Z"
}
],
"total": 12,
"page": 1,
"pages": 1,
"nextSteps": "These are SAVED library avatars in the active workspace. rename_avatar works on any of them by avatarId. Pending (unapproved) drafts are separate: list_draft_avatars."
}
}list_draft_avatars
READREST: GET /api/v2/avatars/drafts
List draft avatars awaiting approval in the active workspace, newest first (paginated).
{
"type": "object",
"properties": {
"page": {
"description": "Page number (default 1).",
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
"limit": {
"description": "Per page (max 100). Each tool documents its own default.",
"type": "integer",
"minimum": 1,
"maximum": 100
},
"workspace": {
"description": "Target workspace: a slug, id, or exact name from list_workspaces. Omit to use this connection's default workspace. Must be inside the credential's grant and your current access; overrides the connection-level X-Workspace-Id header.",
"type": "string"
}
},
"$schema": "http://json-schema.org/draft-07/schema#"
}{
"success": true,
"data": {
"workspace": {
"id": "6a18c36ee586c7e44e4ece67",
"name": "Client A",
"slug": "client-a"
},
"drafts": [
{
"avatarId": "avt_9f8e7d6c5b4a3210",
"name": "Maya",
"imageUrl": "https://cdn.ghostfeed.ai/avatars/drafts/avt_9f8e7d6c5b4a3210.png",
"createdBy": "64f1c2a1b2c3d4e5f6071829",
"createdAt": "2026-07-18T11:00:00.000Z"
}
],
"total": 1,
"page": 1,
"pages": 1,
"nextSteps": "Approve the ones to keep (approve_avatar). You cannot delete drafts; the user manages or discards the rest from the dashboard."
}
}list_image_models
READREST: GET /api/v2/image-models
List the image models create_avatar can use, with per-image credit cost, so you can offer the user options with prices.
No input. Call with no arguments.
{
"success": true,
"data": {
"models": [
{
"id": "gemini_flash",
"label": "Gemini Flash",
"creditCost": 1,
"provider": "google",
"isDefault": true
},
{
"id": "gpt_image",
"label": "GPT Image",
"creditCost": 3,
"provider": "openai",
"isDefault": false
}
],
"nextSteps": "Pass a chosen id as create_avatar `model` (default is the isDefault one). creditCost is per image."
}
}