By default, the Notetaker bot appears in a meeting as a blank participant tile. Custom video output replaces that tile with an image you upload: your product logo, a recording-notice card, or any other branding. The image appears as the bot’s camera feed, so the bot looks like a participant with their camera on. This feature is sometimes called the bot avatar.
You upload the image once on a configuration (or per Notetaker), and every bot governed by that configuration uses it. No avatar field or separate avatar API exists; everything goes through notetaker_settings.video_output.
How custom video output works
Section titled “How custom video output works”video_output is an object inside notetaker_settings that holds a static image. When the bot joins a meeting on Google Meet, Microsoft Teams, or Zoom, the image shows as the bot’s camera feed. On any other meeting provider, the bot joins normally without showing the image.
Two things to know when designing the image:
- Author it at a 16:9 aspect ratio, for example 1280x720; other ratios are letterboxed or cropped.
- Text in the image appears backwards (mirrored) in the recording. Keep that in mind if the image carries a readable message, such as a recording notice.
A broken image never blocks a recording: if the image can’t be used at meeting time, the bot still joins, just without it.
You can set video_output in four places. It follows the standard inheritance chain, so the nearest layer that sets it wins:
| Endpoint | Multipart JSON part name |
|---|---|
POST /v3/notetakers/configs | config |
PATCH /v3/notetakers/configs/<CONFIG_ID> | config |
POST /v3/notetakers (or the grant-based invite) | notetaker |
PATCH /v3/notetakers/<NOTETAKER_ID> (or the grant-based update) | notetaker |
Calendar sync and event sync requests don’t accept video_output. Set it on an application or workspace configuration instead so calendar-scheduled bots inherit it.
Upload an image with multipart
Section titled “Upload an image with multipart”Multipart is the recommended upload path: the file part limit is 4 MiB (4,194,304 bytes), roughly 3 times the base64 budget, with no encoding overhead. Send the request as multipart/form-data with the JSON body in one part and the image in another, and point video_output.file_key at the image part’s name.
curl --request PATCH \ --url "https://api.us.nylas.com/v3/notetakers/configs/<CONFIG_ID>" \ --header "Authorization: Bearer <NYLAS_API_KEY>" \ -F 'config={"notetaker_settings":{"video_output":{"file_key":"avatar"}}};type=application/json' \ -F "avatar=@./brand.png;type=image/png"A few rules keep multipart requests unambiguous:
- The JSON part must be named
configon the configuration endpoints andnotetakeron the Notetaker endpoints (see the table above). The wrong name returns400 Bad Requestwithmultipart config part is requiredormultipart notetaker part is required. file_keycan be any string, but it must match the name of exactly one file part in the same request. In the example,avataris just a label;imageorbrandwork equally well.- Every file part in the request must be referenced by a
file_key, or the request fails withmultipart request includes unreferenced file parts. - The
Content-Typeyou declare on the file part isn’t trusted. Nylas detects the format from the file bytes.
Upload a small image with JSON and base64
Section titled “Upload a small image with JSON and base64”For small images, skip multipart and send the bytes inline on a normal application/json request. Pass media_type and data together; the decoded image must be 1,376,256 bytes (about 1.31 MB) or smaller, and the whole JSON body is capped at 6.25 MiB.
curl --request PATCH \ --url "https://api.us.nylas.com/v3/notetakers/configs/<CONFIG_ID>" \ --header "Authorization: Bearer <NYLAS_API_KEY>" \ --header "Content-Type: application/json" \ --data '{ "notetaker_settings": { "video_output": { "media_type": "image/png", "data": "<BASE64_IMAGE_BYTES>" } } }'The two envelopes don’t mix. file_key on a JSON request returns video_output.file_key requires multipart/form-data, and data on a multipart request returns video_output.data requires application/json. Likewise, file_key can’t be combined with media_type or data in the same object, and the declared media_type must match what the bytes actually are.
Image limits and formats
Section titled “Image limits and formats”Nylas validates every upload by inspecting the actual file content, so a mislabeled file fails with video_output media_type does not match file content rather than being stored incorrectly. Re-uploading an identical image is harmless; it doesn’t create a duplicate copy.
| Constraint | Value |
|---|---|
| Formats | PNG, JPEG, static WebP (animated WebP is rejected) |
| Maximum dimensions | 3840x2160 pixels, and a pixel count of at most 8,294,400 |
| Maximum size, multipart part | 4 MiB (4,194,304 bytes) |
| Maximum size, base64 (decoded) | 1,376,256 bytes (about 1.31 MB) |
| Whole-body cap, multipart | About 7.6 MiB |
| Whole-body cap, JSON | 6.25 MiB |
Read the stored image metadata
Section titled “Read the stored image metadata”Responses never echo the uploaded bytes, the file_key, or internal storage keys. Instead, both reads and writes return four read-only fields under notetaker_settings.video_output so you can confirm what’s stored and preview it:
{ "notetaker_settings": { "video_output": { "media_type": "image/png", "size": 184320, "preview_url": "https://storage.googleapis.com/...", "preview_url_expires_at": 1786128794 } }}preview_url is a signed URL that’s valid for 1 hour; preview_url_expires_at is the Unix timestamp when it stops working. Don’t cache the URL; fetch the configuration again when you need a fresh one. Sending size, preview_url, or preview_url_expires_at on a write returns video_output response metadata is read-only.
Replace, keep, or disable the image
Section titled “Replace, keep, or disable the image”PATCH requests are presence-aware, so you control the image without re-sending up to 4 MiB of image bytes on every settings change. The four request shapes behave differently:
| Request body | Effect |
|---|---|
video_output omitted | The existing image is preserved. |
"video_output": { ...new image... } | The existing image is replaced. |
"video_output": {} | Video output is disabled at this configuration layer. |
"notetaker_settings": null | The whole settings layer is cleared, including the image. |
"video_output": null isn’t a supported way to clear the image; use the empty object {}. Disabling at one layer doesn’t delete images stored on other layers, so a per-notetaker {} can switch off an image inherited from the application configuration for one bot.
Troubleshoot upload errors
Section titled “Troubleshoot upload errors”All validation failures return 400 Bad Request with a specific message, so the error text tells you which rule you hit. The most common ones:
| Error message | Fix |
|---|---|
multipart config part is required / multipart notetaker part is required | Name the JSON part config on config endpoints, notetaker on Notetaker endpoints. |
video_output.file_key must reference exactly one multipart file | The file_key value doesn’t match a file part name (or matches several). |
multipart request includes unreferenced file parts | Remove file parts that no file_key points to. |
video_output.media_type is required when data is present | Send media_type and data together. |
video_output.data must decode to 1376256 bytes or smaller | The image is too big for base64; switch to multipart. |
video_output must be PNG, JPEG, or static WebP | Convert the image; animated WebP is also rejected. |
video_output media_type does not match file content | The declared type doesn’t match the bytes; fix the media_type. |
video_output image dimensions must be 3840x2160 pixels or smaller and no more than 8294400 total pixels | Resize the image. |
request body is too large | Stay under 7.6 MiB (multipart) or 6.25 MiB (JSON). |
Upload failures outside your control surface as a generic 500 Internal Server Error. A failed request never leaves a partially stored image, so it’s always safe to retry.
What’s next
Section titled “What’s next”- Notetaker configurations for the inheritance chain your image travels down.
- Notetaker custom announcements for the chat messages the bot posts when it joins.
- Update a Notetaker configuration in the API reference.