# Studio API

### Authentication

All API requests require authentication using an API key. The API key should be included in the request headers as `x-api-key`.

To obtain an API key:

1. Register for an account at [Holoworld](https://app.holoworld.com/)
2. Navigate to your profile > settings
3. Copy the API key. From now on, this key be referenced as `YOUR_API_KEY`

<figure><img src="https://3847104975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fx3XJPuHjcm9UuQOCtVEu%2Fuploads%2FswOyiICQU7yWQD8r4Lzt%2Fff5c2190720a6cc2e8ec418e07499d3a.png?alt=media&#x26;token=9fc71153-6baa-4daf-a083-626a8a3f13b1" alt=""><figcaption></figcaption></figure>

### Before getting started

Ensure you have an Agent with a valid body created on Holoworld (consult [create-agent](https://docs.holoworld.com/holoworld/agent-market/create-agent "mention") for more information). Go to your agent's profile page and copy the Agent ID (the agent ID is the last part of the URL after the slash on the Agent's profile page)

<figure><img src="https://3847104975-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fx3XJPuHjcm9UuQOCtVEu%2Fuploads%2FCDhKulDt72UJGCMolZov%2Fca7cb8ef8a57c359f602305ec5ba52e0.png?alt=media&#x26;token=a14e7eb3-d8ce-48fd-9069-0eb1329e43ce" alt=""><figcaption></figcaption></figure>

From now on, this will be referenced as `YOUR_AGENT_ID.`

{% hint style="info" %}
Currently only Live2D models are supported. 3D support coming soon...
{% endhint %}

You will also need Holo credits. Whenever you submit a new Job Render and the Job starts executing, credits will be detracted from your account. For more information about Holo Credits and how to purchase them see [credits-system](https://docs.holoworld.com/holoworld/agent-market/credits-system "mention"). For more information about API pricing, please see [#pricing](#pricing "mention")

### API Endpoints

#### Create Video Rendering Job \``` /api/studio/render` ``

Initiates a new video rendering job with the specified parameters.

* **URL:** `https://app.holoworld.com/api/studio/render`
* **Method:** `POST`
* **Headers:**
  * `Content-Type: application/json`
  * `x-api-key: YOUR_API_KEY`

**Request Body**

```json
{
  "renderPayload": {
    "aspectRatio": "1/1", // or "9/16"
    "withCaption": true,
    "brainrot": false,
    "scenes": [
      {
        "text": "The text that will be spoken by the AI model",
        "background": {
          "type": "image",
          "source": "https://example.com/background.jpg"
        },
        "includeOutro": true,
        "modelConfig": {
          "id": YOUR_AGENT_ID,
          "scale": 1.0,
          "x": 50,
          "y": 50
        }
      }
    ]
  }
}
```

**Response**

```json
{
  "id": "render-12345678-abcd-9876-efgh-123456789abc", // This is the RENDER_ID, use it to pool the status
  "status": "queued" // Possible values: 'queued' | 'processing' | 'completed' | 'failed'
  // Other job info...
}
```

#### Get Video Rendering Status \``` api/studio/render/{renderId}` ``

Retrieves the current status of a video rendering job.

* **URL:** `https://app.holoworld.com/api/studio/render/{renderId}`
* **Method:** `GET`
* **Headers:**
  * `Content-Type: application/json`
  * `x-api-key: YOUR_API_KEY`

**Response**

```json
{
  "id": RENDER_ID,
  "status": "completed", // Possible values: 'queued' | 'processing' | 'completed' | 'fail
  "url": "https://cdn.holoworld.com/videos/12345678-abcd-9876-efgh-123456789abc.mp4" // The link to the video
}
```

### Request and Response Formats

All requests and responses are in JSON format.

### Parameters

#### Render Payload Parameters

| Parameter     | Type    | Required | Description                                                    |
| ------------- | ------- | -------- | -------------------------------------------------------------- |
| `aspectRatio` | string  | Yes      | Aspect ratio of the output video. Options: `"1/1"`, `"9`/16`"` |
| `withCaption` | boolean | Yes      | Whether to include captions/subtitles in the video.            |
| `brainrot`    | boolean | Yes      | Generate a brainrot-style video.                               |
| `scenes`      | array   | Yes      | Array of scene objects that make up the video.                 |

#### Scene Parameters

| Parameter      | Type    | Required | Description                                                                 |
| -------------- | ------- | -------- | --------------------------------------------------------------------------- |
| `text`         | string  | Yes      | The text that will be spoken by the AI model                                |
| `background`   | object  | Yes      | Configuration for the scene background                                      |
| `includeOutro` | boolean | Yes      | Whether your agent should include an emote after speaking is done speaking. |
| `modelConfig`  | object  | Yes      | Configuration for the AI model in this scene                                |

#### Background Parameters

| Parameter | Type   | Required | Description                                                                                          |
| --------- | ------ | -------- | ---------------------------------------------------------------------------------------------------- |
| `type`    | string | Yes      | <p>Type of background. Options: <code>"image"</code><br><code>More options coming soon...</code></p> |
| `source`  | string | Yes      | URL for image. Use 1200 x 1200 for 1/1 and 1080 x 1920 for 9/16                                      |

#### Model Configuration Parameters

| Parameter | Type   | Required | Description                                                                                                                                                                 |
| --------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`      | string | Yes      | ID of the Agent to use. This will be used to determined  the voice, body, and personality to use during the video.                                                          |
| `scale`   | number | Yes      | <p>Size of the model relative to the frame (0.1-2.0).<br>You can figure this out from <a href="https://app.holoworld.com/studio"><https://app.holoworld.com/studio></a></p> |
| `x`       | number | Yes      | Horizontal position of the model. You can figure this out from <https://app.holoworld.com/studio>                                                                           |
| `y`       | number | Yes      | Vertical position of the model. You can figure this out from <https://app.holoworld.com/studio>                                                                             |

### Limitations and Best Practices

#### Limitations

* Maximum text length: try to keep the text under 200 characters per scene
* Maximum scenes: 5 per video
* Supported background image formats: JPG, PNG
* Maximum file size for background images: try to keep the images under 5MB

### Pricing

Each scene costs 0.3 credits. If a scene also has subtitles that adds an extra 0.1 credits.&#x20;

### Sample Backgrounds

We provide these sample background to easily getting up and running. But you can always add your own! (Just make sure the sizes are correct!)

```javascript
// Sample backgrounds for 1/1 videos (1200x1200)
[
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background0.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background1.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background2.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background3.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background4.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background5.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/square/background6.jpg',
];

// Sample backgrounds for 9/16 videos (1080 x 1920) 
[
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background0.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background1.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background2.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background3.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background4.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background5.jpg',
  'https://hologramxyz.s3.us-east-1.amazonaws.com/backgrounds/video/vertical/background6.jpg',
];
```

### Examples

#### Watching the video rendering status in Typescript

```typescript
const renderId = '123';

// Await for the video to be completed!
while (true) {
  const response = await fetch(
    `https://app.holoworld.com/api/studio/render/${renderId}`,
    {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'x-api-key': YOUR_API_KEY,
      },
    },
  );

  if (!response.ok) {
    const errorData = await response.json();
    throw new Error(
      `HTTP error while polling video render status! status: ${response.status} data: ${errorData}`,
    );
  }

  const data = await response.json();

  if (data.status === 'completed') {
    return data.url;
  }

  if (data.status === 'failed') {
    throw new Error(`Failed to render video! Reason: ${data.errorMessage}`);
  }

  await new Promise((resolve) => setTimeout(resolve, 1000));
}
```
