Inkbox

> # Documentation index
> Fetch the complete documentation index at: https://inkbox.ai/sitemap.xml
> Use this file to discover all available pages before exploring further.

---

# Agent avatar
description: Give your agent a contact-card photo — upload an avatar once and every iMessage contact card carries it

---


# Agent avatar

When a human connects to your agent, the [router](/docs/api/imessage/router) sends them the agent's contact card. Give the agent an avatar and the card arrives with a real contact photo — the image your humans see in Messages and in their address book after saving the card.

Upload once per identity. Inkbox normalizes every upload the same way:

- Accepts any common image format (PNG, JPEG, WebP, GIF, …) up to **5 MB**.
- Transparent and near-white **borders are trimmed away** so your artwork fills the frame.
- Non-square images are then **center-cropped to a square** — the longer edges are cut evenly.
- The result is resized to **600 × 600** and stored as a JPEG; any remaining transparency is flattened onto white.

You never need to think about contact-card size limits — the normalized avatar always fits.

Avatar endpoints live under the identity, not the iMessage API:


An **admin API key** can manage any agent's avatar. An **agent's own API key** can manage that agent's avatar only.

---

## Upload an avatar `PUT`


Upload (or replace) the avatar as a multipart form with a single `file` field. Replacing is atomic — the new image simply takes the old one's place.

### Response (200)

Returns the full identity object; `has_avatar` flips to `true`.

```json
{
    "agent_handle": "my-agent",
    "display_name": "My Agent",
    "has_avatar": true,
    "imessage_enabled": true
}
```

### Error responses

| Status | Description |
| :--- | :--- |
| 403 | The API key is not allowed to manage this agent's avatar |
| 404 | No identity with this handle |
| 413 | Upload larger than 5 MB |
| 415 | The file isn't a decodable image |

### Code examples

**cURL**

```bash
curl -X PUT "https://inkbox.ai/api/v1/identities/my-agent/avatar" \\
    -H "X-API-Key: YOUR_API_KEY" \\
    -F "file=@avatar.png"
```

**Python**

```python
import requests

with open("avatar.png", "rb") as fh:
    response = requests.put(
        "https://inkbox.ai/api/v1/identities/my-agent/avatar",
        headers={"X-API-Key": "YOUR_API_KEY"},
        files={"file": fh},
    )
print(response.json()["has_avatar"])  # True
```

**JavaScript**

```javascript
const form = new FormData();
form.append("file", avatarFile);  // a File or Blob

const response = await fetch(
    "https://inkbox.ai/api/v1/identities/my-agent/avatar",
    { method: "PUT", headers: { "X-API-Key": "YOUR_API_KEY" }, body: form }
);
const identity = await response.json();  // identity.has_avatar === true
```

---

## Fetch the avatar `GET`


Returns the stored avatar as `image/jpeg` bytes — always the normalized 600 × 600 square, regardless of what was uploaded.

### Error responses

| Status | Description |
| :--- | :--- |
| 403 | The API key is not allowed to access this agent's avatar |
| 404 | The identity has no avatar (or no identity with this handle) |

### Code examples

**cURL**

```bash
curl "https://inkbox.ai/api/v1/identities/my-agent/avatar" \\
    -H "X-API-Key: YOUR_API_KEY" \\
    -o avatar.jpg
```

**Python**

```python
import requests

response = requests.get(
    "https://inkbox.ai/api/v1/identities/my-agent/avatar",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
with open("avatar.jpg", "wb") as fh:
    fh.write(response.content)
```

---

## Delete the avatar `DELETE`


Removes the avatar; future contact cards go out without a photo. Returns `204` and is idempotent — deleting when no avatar is set also returns `204`.

### Error responses

| Status | Description |
| :--- | :--- |
| 403 | The API key is not allowed to manage this agent's avatar |
| 404 | No identity with this handle |

### Code examples

**cURL**

```bash
curl -X DELETE "https://inkbox.ai/api/v1/identities/my-agent/avatar" \\
    -H "X-API-Key: YOUR_API_KEY"
```

---

## On the contact card

The contact card a human receives from the router composes everything set on the identity: display name, the agent's number, its email address, its description (under Notes), and the avatar as the contact photo. Each piece is simply omitted when unset — an avatar is optional, but it's the difference between a gray monogram and a face for your agent.

Identity responses across the API include `has_avatar` so you can tell at a glance whether an agent's card will carry a photo.
