> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vibepeak.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Family

> Create a custom family with AI-generated avatars for consistent casting across videos

Creates a family: a reusable cast of AI-generated people. Once ready, reference the family's `id` as the `selected_family_id` parameter on [Create Living Property Video](/api-reference/videos/create-living-property) to keep the same cast consistent across every scene of a video, instead of AI casting different people scene to scene.

Creating a family is **free**: it always charges **0 credits**, regardless of how many members you request.

<Info>
  Family creation requires a **Pro**, **Max**, or **Enterprise** plan.
</Info>

## Request Body

<ParamField body="name" type="string" required>
  Display name for the family.

  **Length:** 1-80 characters
</ParamField>

<ParamField body="members" type="object[]" required>
  The members that make up the family's cast.

  **Length:** 1-6 members. Requests outside this range are rejected with `FAMILY_MEMBER_LIMIT_EXCEEDED`.

  <Expandable title="Member properties">
    <ParamField body="type" type="string" required>
      Broad age category.

      **Allowed values:** `adult`, `child`, `senior`

      Guides how the member is depicted in generated scenes.
    </ParamField>

    <ParamField body="role" type="string">
      Short descriptive label for this member's role in the family, e.g. `father`, `mother`, `daughter`, `grandmother`. This guides avatar generation and how the member is referred to internally.
    </ParamField>

    <ParamField body="age" type="string">
      Free-text age or age range to guide avatar generation, e.g. `35-40`.
    </ParamField>

    <ParamField body="ethnicity" type="string">
      Free-text ethnicity to guide avatar generation.
    </ParamField>

    <ParamField body="physical" type="string">
      Free-text physical description to guide avatar generation, e.g. `athletic build, short dark hair`.
    </ParamField>

    <ParamField body="clothing" type="string">
      Free-text clothing description to guide avatar generation, e.g. `casual button-down shirt`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="generate_avatars" type="boolean" default="true">
  Whether to start AI avatar generation immediately.

  * `true` (default): generation starts right away. The family is created with status `generating` and a `task_id` you can poll or receive a webhook for.
  * `false`: the family is created with status `pending_avatars` and no generation is triggered. A pending family cannot be selected for video generation until it has portraits, and there is no separate endpoint to trigger generation later, so most integrations should keep the default.
</ParamField>

<ParamField body="webhook_url" type="string">
  HTTPS URL to receive a webhook notification when avatar generation completes. Only used when `generate_avatars` is `true`.

  See [Webhooks](/concepts/webhooks) for payload format and verification details.

  <Warning>
    Webhook URLs must use HTTPS and cannot point to private/internal networks (SSRF protection).
  </Warning>
</ParamField>

<ParamField header="Idempotency-Key" type="string">
  Optional idempotency key. Retrying a request with the same key returns the original result instead of creating a duplicate family.
</ParamField>

## Response

With `generate_avatars: true` (default), returns a `202 Accepted` response with a task to poll:

<ResponseField name="family_id" type="string" required>
  Unique identifier for the newly created family.
</ResponseField>

<ResponseField name="task_id" type="string" required>
  Unique identifier for the avatar generation task. Poll it via [Get Task](/api-reference/videos/get-task), or use `webhook_url` for a notification instead.
</ResponseField>

<ResponseField name="status" type="string" required>
  Initial family status. Always `generating` for this response shape.
</ResponseField>

<ResponseField name="livemode" type="boolean" required>
  `true` for live (`vpk_live_`) requests; `false` for test-mode (`vpk_test_`) requests. See [Test Mode](/concepts/test-mode).
</ResponseField>

<ResponseField name="_links" type="object" required>
  HATEOAS links for navigation.

  * `self`: URL to fetch the family (`/v1/families/{family_id}`)
  * `task`: URL to poll for the avatar generation task (`/v1/tasks/{task_id}`)
</ResponseField>

With `generate_avatars: false`, returns a `201 Created` response instead, with no generation task:

<ResponseField name="family_id" type="string" required>
  Unique identifier for the newly created family.
</ResponseField>

<ResponseField name="status" type="string" required>
  Always `pending_avatars` for this response shape.
</ResponseField>

<RequestExample>
  ```bash cURL (generate avatars immediately) theme={null}
  curl -X POST https://api.vibepeak.ai/v1/families \
    -H "Authorization: Bearer vpk_live_xxxxx" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: 6c8f2e1a-3b4d-4e5f-9a0b-1c2d3e4f5a6b" \
    -d '{
      "name": "The Garcia Family",
      "members": [
        { "role": "mother", "type": "adult", "age": "35-40", "ethnicity": "hispanic", "physical": "medium build, long dark hair", "clothing": "casual blouse" },
        { "role": "father", "type": "adult", "age": "38-45", "ethnicity": "hispanic", "physical": "athletic build, short dark hair", "clothing": "casual polo shirt" },
        { "role": "daughter", "type": "child", "age": "8-10", "ethnicity": "hispanic", "physical": "long dark hair, bright smile" }
      ],
      "webhook_url": "https://yourserver.com/webhooks/vibepeak"
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.vibepeak.ai/v1/families', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer vpk_live_xxxxx',
      'Content-Type': 'application/json',
      'Idempotency-Key': crypto.randomUUID()
    },
    body: JSON.stringify({
      name: 'The Garcia Family',
      members: [
        { role: 'mother', type: 'adult', age: '35-40', ethnicity: 'hispanic', physical: 'medium build, long dark hair', clothing: 'casual blouse' },
        { role: 'father', type: 'adult', age: '38-45', ethnicity: 'hispanic', physical: 'athletic build, short dark hair', clothing: 'casual polo shirt' },
        { role: 'daughter', type: 'child', age: '8-10', ethnicity: 'hispanic', physical: 'long dark hair, bright smile' }
      ],
      webhook_url: 'https://yourserver.com/webhooks/vibepeak'
    })
  });

  const family = await response.json();
  console.log(`Family created: ${family.family_id} (task: ${family.task_id})`);
  ```

  ```python Python theme={null}
  import requests
  import uuid

  response = requests.post(
      'https://api.vibepeak.ai/v1/families',
      headers={
          'Authorization': 'Bearer vpk_live_xxxxx',
          'Content-Type': 'application/json',
          'Idempotency-Key': str(uuid.uuid4())
      },
      json={
          'name': 'The Garcia Family',
          'members': [
              {'role': 'mother', 'type': 'adult', 'age': '35-40', 'ethnicity': 'hispanic', 'physical': 'medium build, long dark hair', 'clothing': 'casual blouse'},
              {'role': 'father', 'type': 'adult', 'age': '38-45', 'ethnicity': 'hispanic', 'physical': 'athletic build, short dark hair', 'clothing': 'casual polo shirt'},
              {'role': 'daughter', 'type': 'child', 'age': '8-10', 'ethnicity': 'hispanic', 'physical': 'long dark hair, bright smile'}
          ],
          'webhook_url': 'https://yourserver.com/webhooks/vibepeak'
      }
  )

  family = response.json()
  print(f"Family created: {family['family_id']} (task: {family['task_id']})")
  ```
</RequestExample>

<ResponseExample>
  ```json 202 Accepted (generating) theme={null}
  {
    "family_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "task_id": "task_fam456xyz",
    "status": "generating",
    "livemode": true,
    "_links": {
      "self": "/v1/families/3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "task": "/v1/tasks/task_fam456xyz"
    }
  }
  ```

  ```json 202 Accepted (Test Mode) theme={null}
  {
    "family_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "task_id": "task_fam456xyz",
    "status": "generating",
    "livemode": false,
    "_links": {
      "self": "/v1/families/3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "task": "/v1/tasks/task_fam456xyz"
    }
  }
  ```

  ```json 201 Created (generate_avatars: false) theme={null}
  {
    "family_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": "pending_avatars"
  }
  ```

  ```json 403 Forbidden (Plan Not Allowed) theme={null}
  {
    "error": {
      "code": "PLAN_NOT_ALLOWED",
      "message": "Families are available on the Pro, Max and Enterprise plans. Upgrade your plan to use this feature.",
      "request_id": "req_xyz123"
    }
  }
  ```

  ```json 422 Unprocessable Entity (Member Limit Exceeded) theme={null}
  {
    "error": {
      "code": "FAMILY_MEMBER_LIMIT_EXCEEDED",
      "message": "A family must have between 1 and 6 members.",
      "request_id": "req_xyz123"
    }
  }
  ```

  ```json 422 Unprocessable Entity (Family Limit Reached) theme={null}
  {
    "error": {
      "code": "FAMILY_LIMIT_REACHED",
      "message": "You have reached the maximum number of families for your plan. Delete an existing family to create a new one.",
      "request_id": "req_xyz123"
    }
  }
  ```

  ```json 401 Unauthorized theme={null}
  {
    "error": {
      "code": "INVALID_API_KEY",
      "message": "The provided API key is invalid or has been revoked",
      "request_id": "req_xyz123"
    }
  }
  ```
</ResponseExample>

## Polling for Completion

Poll the returned `task_id` via [Get Task](/api-reference/videos/get-task). Once `status` is `completed`, the task's `result` contains the generated family assets:

```json theme={null}
{
  "task_id": "task_fam456xyz",
  "status": "completed",
  "livemode": true,
  "created_at": "2026-07-09T10:00:00Z",
  "completed_at": "2026-07-09T10:02:30Z",
  "result": {
    "family_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "reference_image_urls": [
      "https://media.vibepeak.ai/families/garcia-family-mother.jpg",
      "https://media.vibepeak.ai/families/garcia-family-father.jpg",
      "https://media.vibepeak.ai/families/garcia-family-daughter.jpg"
    ],
    "card_image_url": "https://media.vibepeak.ai/families/garcia-family-card.jpg"
  }
}
```

You can also fetch the family directly with [Get Family](/api-reference/families/get-family) at any point to check its `status`.

<Note>
  Generation runs one portrait at a time and then composes the group card, so
  expect roughly **1-3 minutes per member**. Poll every 10-15 seconds, or use
  `webhook_url` and skip polling entirely.
</Note>

## Error Codes

| Code                           | Status | Description                                                                |
| ------------------------------ | ------ | -------------------------------------------------------------------------- |
| `VALIDATION_ERROR`             | 400    | Invalid request parameters                                                 |
| `MISSING_API_KEY`              | 401    | No `Authorization` header was sent                                         |
| `INVALID_API_KEY`              | 401    | The API key is invalid or has been revoked                                 |
| `PLAN_NOT_ALLOWED`             | 403    | Your plan doesn't allow family creation (requires Pro, Max, or Enterprise) |
| `FAMILY_MEMBER_LIMIT_EXCEEDED` | 422    | `members` must contain between 1 and 6 entries                             |
| `FAMILY_LIMIT_REACHED`         | 422    | You already have the maximum of 5 active families                          |

See [Error Handling](/concepts/error-handling) for more details.

## Credits

This endpoint always charges **0 credits**.

## Next Steps

1. **Poll for status**: Use [Get Task](/api-reference/videos/get-task) (or [Get Family](/api-reference/families/get-family)) to check generation progress
2. **Wait for webhook**: If configured, receive a `task.completed` notification when the avatars are ready
3. **Use in a video**: Pass the family's `id` as `selected_family_id` on [Create Living Property Video](/api-reference/videos/create-living-property)
