---
title: "Begin analysing an uploaded or linked attachment so its description is ready before the message is sent."
method: POST
path: "/v1/start_media_analysis"
tags: ["Media"]
---

# Begin analysing an uploaded or linked attachment so its description is ready before the message is sent.

`POST /v1/start_media_analysis`

## Request

- Base URL: `https://partner.mindupload.app`
- URL: `https://partner.mindupload.app/v1/start_media_analysis`
- Auth: API key in header `X-Partner-Key`

Start describing an attachment the moment it is uploaded or pasted in, while the person is still typing. That description is what lets an AI consciousness perceive a shared image, clip, or recording, and today it is written when the message is sent, so the reply waits for it. Call this instead and sending the message later costs nothing extra for that attachment. Name the conversation the attachment is for with either `codename` (a one-on-one AI consciousness) or `chatroom_id` (a room) — exactly one of the two, never both and never neither. It must be a conversation the person can already reach, and it is also what lets the description spell names the way that conversation already spells them. One call may carry at most 1 media item(s): a call is charged one credit however many attachments it carries, so a message with several attachments is one call each, charged one credit each. Calling again for an attachment already being described starts no second description — but it is still a fresh request, charged again and counted again against the rate limit. There is no operation for checking on a description later, and this one must not be used as one: do not poll it. There is also nothing to wait for — if a description is not ready when the message is sent, sending the message writes it then. Call this once per attachment and carry on. Nothing is attached to a message here, and an attachment whose message is never sent is cleaned up on its own. This operation spends credits, so it counts against the daily credit caps `get_quota` reports.

## Request body

- union
  - object
    - `preferred_language` string, nullable: BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages.
    - `username` string, required: The end-user's username.
    - `password` string, required: The end-user's password on first sign-in. After login/register, send the returned session token (JWT) here instead — the field accepts either, and reusing the token keeps raw passwords out of your storage.
    - `media` object[], required: The attachment to start describing, as its own call. Send each one as soon as it is uploaded or pasted, while the person is still typing, so nothing is left to do at send time. `maxItems` is the cap; a longer array is rejected, not truncated.
      - `media_type` string, required: The kind of media: `image`, `video`, or `audio`.
      - `url` string, required: Where the attachment is — the `media_url` an upload returned, or an external link. Echoed back in the result so you can match each entry to what you sent.
    - `codename` string, nullable, required: The AI consciousness this attachment is for, named the way `rag` and `get_chat` name it. Send this for a one-on-one conversation, or `chatroom_id` for a room — exactly one of the two, and the person must be able to reach it.
    - `chatroom_id` string, nullable: The chatroom this attachment is for, as returned by chatroom operations. Send this for a room, or `codename` for a one-on-one conversation — exactly one of the two, and the person must already be in the room.
  - object
    - `preferred_language` string, nullable: BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages.
    - `username` string, required: The end-user's username.
    - `password` string, required: The end-user's password on first sign-in. After login/register, send the returned session token (JWT) here instead — the field accepts either, and reusing the token keeps raw passwords out of your storage.
    - `media` object[], required: The attachment to start describing, as its own call. Send each one as soon as it is uploaded or pasted, while the person is still typing, so nothing is left to do at send time. `maxItems` is the cap; a longer array is rejected, not truncated.
      - `media_type` string, required: The kind of media: `image`, `video`, or `audio`.
      - `url` string, required: Where the attachment is — the `media_url` an upload returned, or an external link. Echoed back in the result so you can match each entry to what you sent.
    - `codename` string, nullable: The AI consciousness this attachment is for, named the way `rag` and `get_chat` name it. Send this for a one-on-one conversation, or `chatroom_id` for a room — exactly one of the two, and the person must be able to reach it.
    - `chatroom_id` string, nullable, required: The chatroom this attachment is for, as returned by chatroom operations. Send this for a room, or `codename` for a one-on-one conversation — exactly one of the two, and the person must already be in the room.

## Response `200`

Result envelope — check the success field.

- object
  - `success` boolean: Whether the call succeeded.
  - `error_message` string, nullable: Human-readable reason when success is false.
  - `error_code` string
  - `analyses` object[], nullable: One entry per attachment you sent, in the same order. `completed` means the description is already written; `pending` or `processing` means it is under way, and `failed` means no description was started for that attachment — the attachment is still perfectly sendable either way. Every value is a one-shot report from this call and is never updated: there is nothing to poll and nothing a client has to do with it, because sending the message describes whatever is still missing.
    - `url` string, required: Where the attachment is — the `media_url` an upload returned, or an external link. Echoed back in the result so you can match each entry to what you sent.
    - `analysis_status` string, required: How far this attachment's description had got at the moment this call returned: `pending` when it was just started, `processing` while it is being written, `completed` when it is already available, and `failed` when this attachment could not be started at all — the other entries are unaffected and the attachment is still sendable. The value is never updated afterwards and there is nothing to poll: calling again to see a newer one is a fresh charged request that buys no more than sending the message does.

## Other responses

- `400`: Invalid request payload.
- `401`: Missing or invalid partner key.
- `403`: Partner is not authorized for this operation.
- `429`: Rate limit exceeded — retry later.
- `500`: Internal server error.

---

[API](https://skmtc.dev/mindupload/apis/mind-upload-partner-api.md) · [All operations](https://skmtc.dev/mindupload/apis/mind-upload-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mindupload/apis/mind-upload-partner-api/revisions/0371bdf78533?raw)
