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

# 上传媒体

> 上传图片、GIF 或视频，获取可附加到推文的 media_id。仅支持 multipart/form-data。

上传单个图片、GIF 或视频，返回一个 `media_id`，随后可在 [`post_twitter`](/docs/zh/api-reference/twitter/post_twitter-post-twitter) 里附加到推文。经 AIsa 网关代理，地址 `https://api.aisa.one/apis/v1/twitter/upload_media`。

<Warning>
  本端点**仅支持 `multipart/form-data`** —— 请以表单部件上传文件。发送 JSON 请求体会返回 `400 "upload_media requires multipart/form-data with a single media file field"`。
</Warning>

## 前置条件

* 一个 **AIsa API Key**（每次请求作为 Bearer 令牌）。
* 源用户的一次性 **OAuth 授权**。通过 [`POST /apis/v1/twitter/auth_twitter`](/docs/zh/api-reference/twitter/post_twitter-auth-twitter) 绑定你的 X 账号。
* X 会话需持有 `media.write`、`tweet.read`、`users.read`。

## 两步媒体流程

1. **上传** —— `POST /apis/v1/twitter/upload_media` 上传文件 → 返回 `media_id`。
2. **发布** —— `POST /apis/v1/twitter/post_twitter` 传入 `{ "media": { "media_ids": ["<media_id>"] } }`。

<Note>
  `post_twitter` 也支持在单次 multipart 请求里通过 `media_files` 内联文件，从而跳过预上传步骤。当你想把同一素材复用到多条推文，或把大文件上传与发推解耦时，使用 `upload_media`。
</Note>

## 示例

```bash theme={null}
curl -X POST "https://api.aisa.one/apis/v1/twitter/upload_media" \
  -H "Authorization: Bearer $AISA_API_KEY" \
  -F "media_files=@./cat.png;type=image/png"
```

```json 响应 theme={null}
{ "code": 200, "msg": "Media uploaded successfully", "data": { "media_id": "2099415764780605440" } }
```

随后附加：

```bash theme={null}
curl -X POST "https://api.aisa.one/apis/v1/twitter/post_twitter" \
  -H "Authorization: Bearer $AISA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text":"看这只猫","media":{"media_ids":["2099415764780605440"]}}'
```

## 说明

* 文件字段名可用 `media_files`、`media` 或 `file`。
* ≤8MB 的图片走单次上传；更大文件与视频自动分片上传。
* 未挂载的媒体约 24 小时后过期。
* 媒体上传是前置步骤，**不单独计费** —— 发推（`post_twitter`）时才计费。

更多见[错误码](/docs/zh/api-reference/errors)与[限流](/docs/zh/api-reference/rate-limits)。

## 相关

<CardGroup cols={3}>
  <Card title="发布推文" icon="pen" href="/docs/zh/api-reference/twitter/post_twitter-post-twitter">
    通过 `media.media_ids` 附加 media\_id。
  </Card>

  <Card title="绑定 X 账号" icon="key" href="/docs/zh/api-reference/twitter/post_twitter-auth-twitter">
    启动本端点所需的 OAuth 流程。
  </Card>

  <Card title="点赞推文" icon="heart" href="/docs/zh/api-reference/twitter/post_twitter-like-twitter">
    使用同一 OAuth 会话的另一个写端点。
  </Card>
</CardGroup>


## OpenAPI

````yaml openapi/zh/twitter-actions.json POST /twitter/upload_media
openapi: 3.0.3
info:
  title: Twitter Actions API
  version: 1.0.0
  description: >-
    对 X/Twitter 执行写入操作，并通过 AIsa 网关路由。参照官方 X v2 API 端点建模（例如 POST
    /2/users/{id}/following）。
servers:
  - url: https://api.aisa.one/apis/v1
security:
  - BearerAuth: []
paths:
  /twitter/upload_media:
    post:
      summary: 上传媒体（发推前预上传）
      description: >-
        上传单个图片、GIF 或视频，返回一个 `media_id`，随后可在
        [`post_twitter`](/zh/api-reference/twitter/post_twitter-post-twitter)
        里通过 `media.media_ids` 附加到推文。经网关代理，地址
        `https://api.aisa.one/apis/v1/twitter/upload_media`。


        **Content-Type 只支持 `multipart/form-data`。** 请以 multipart 表单部件上传文件。**不要发送
        JSON 请求体** —— JSON 请求会返回 `400 "upload_media requires multipart/form-data
        with a single media file field"`。


        **两步媒体流程：**

        1. `POST /apis/v1/twitter/upload_media` 上传文件 → 返回 `media_id`。

        2. `POST /apis/v1/twitter/post_twitter` 传入 `{ "media": { "media_ids":
        ["<media_id>"] } }`。


        或者，`post_twitter` 也支持在单次 multipart 请求里通过 `media_files` 内联文件，跳过预上传步骤。


        **鉴权：** 需要源用户的 OAuth 会话并绑定到你的 AIsa API Key。首次通过 [`POST
        /apis/v1/twitter/auth_twitter`](/zh/api-reference/twitter/post_twitter-auth-twitter)
        授权账号。


        **权限范围：** 底层 X 会话需持有 `media.write`（以及 `tweet.read`、`users.read`）。


        媒体上传是前置步骤，不单独计费 —— 发推（`post_twitter`）时才计费。
      operationId: uploadTwitterMedia
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - media_files
              properties:
                media_files:
                  type: string
                  format: binary
                  description: >-
                    要上传的媒体文件（`image/*`、`image/gif` 或 `video/*`）。字段名也可用 `media` 或
                    `file`。≤8MB 的图片走单次上传；更大文件与视频自动走分片上传。
                aisa_api_key:
                  type: string
                  description: '可选。通常无需填写 —— 网关会从 `Authorization: Bearer` 头解析你的账号。'
            encoding:
              media_files:
                contentType: image/png, image/jpeg, image/gif, video/mp4
      responses:
        '200':
          description: 上传成功；返回可在 `post_twitter` 中引用的 `media_id`。
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      media_id:
                        type: string
                        description: >-
                          上传媒体的 ID。在 `post_twitter` 的 `media.media_ids`
                          中传入。未挂载的媒体约 24 小时后过期。
              example:
                data:
                  media_id: '2099415764780605440'
        '400':
          description: >-
            非 `multipart/form-data`、缺少文件部件、文件为空或不支持的类型。JSON 请求体会返回
            `"upload_media requires multipart/form-data with a single media file
            field"`。
        '401':
          description: 缺少或无效的 AIsa API Key。
        '403':
          description: >-
            OAuth 会话缺失、过期或缺少 `media.write`。请通过 `POST
            /apis/v1/twitter/auth_twitter` 重新授权。
        '429':
          description: 触发限流 —— 你的 AIsa Key RPM 上限或上游 X 限流。
        '500':
          description: 内部错误。
        '502':
          description: 上游 X API 不可达。可用指数退避重试。
      security:
        - BearerAuth: []
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: AISA API Key
      description: 你的 AIsa API 密钥。经过身份验证的源用户（执行关注操作的账户）由附加到你的密钥的 OAuth 会话决定。

````