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

# 使用 GraphQL API

> 通过 Ayrshare GraphQL API 查找操作、了解参数类型和枚举、创建帖子以及上传媒体。

<h2 id="finding-an-operation">
  查找操作
</h2>

对于受支持的 GraphQL 子集，schema 是权威来源：包括操作根、名称、参数、输入类型和枚举值。描述提供了使用指导，[GraphQL Explorer](https://app.ayrshare.com/graphql-explorer) 会同时展示这两者。对于仅 REST 提供的功能，请使用 [REST API 参考](/docs/apis/overview)。

操作名称沿用其对应的 REST 端点，并采用 camelCase 形式。`GET /history` 对应 `postHistory`，`GET /analytics/social` 对应 `socialAnalytics`，`POST /post` 对应 `createPost`。

<h2 id="queries-read-mutations-write">
  查询用于读取，变更用于写入
</h2>

查询（query）是不会在我们这边更改任何内容的读取和验证操作。变更（mutation）会发布内容或更改状态、启动任务或发送电子邮件。决定根类型的既不是 REST 的 HTTP 动词，也不是调用的成本：

<ul class="custom-bullets">
  <li><code>validatePost</code> 会检查帖子但不发布。</li>
  <li><code>validateMedia</code> 会检查媒体 URL 是否可访问。</li>
  <li><code>generatePost</code> 是查询，因为它不会在我们这边更改任何内容。但它仍计为一次 API 调用，并且每次返回的文本都不同，因此请确保客户端缓存或自动重新获取不会在你不知情的情况下重复调用它。</li>
  <li><code>mediaUploadUrl</code> 是变更，因为它会为你的账户创建一个上传 URL。</li>
  <li><code>linkAnalytics</code> 是变更，因为它可以请求通过电子邮件发送报告。</li>
  <li><code>userBatch</code> 是变更，因为它会启动一个导出任务。</li>
</ul>

请使用 Explorer 或 schema 确认每个受支持操作的根类型。

<h2 id="creating-a-post">
  创建帖子
</h2>

`createPost` 只接受一个 `input` 参数，因此整个帖子就是一个对象：

```graphql theme={"system"}
mutation {
  createPost(input: {
    post: "Hello from GraphQL"
    platforms: [LINKEDIN]
    idempotencyKey: "post-2026-09-01-001"
  }) {
    status
    id
  }
}
```

该输入与文档中的 [REST 发布端点](/docs/apis/post/post) 一致，包括各社交网络的选项对象，以及可接受多种 JSON 结构的 REST 形式：

```graphql theme={"system"}
mutation {
  createPost(input: {
    post: "New video"
    platforms: [YOUTUBE]
    mediaUrls: ["https://example.com/video.mp4"]
    idempotencyKey: "youtube-video-001"
    youTubeOptions: {
      title: "My video"
      visibility: PUBLIC
    }
  }) {
    status
    id
    postIds { platform postUrl }
  }
}
```

一个帖子可能在一个社交网络上成功，而在另一个社交网络上失败。这并不属于请求失败，请参见[错误](/docs/apis/graphql/errors#partial-success-on-multi-network-posts)。

<h2 id="argument-types">
  参数类型
</h2>

大多数参数都是普通的字符串、数字和布尔值。有三种情况值得了解。

<h3 id="enums">
  枚举
</h3>

许多取值范围固定的字符串参数都是 GraphQL 枚举，书写时**不加引号且使用大写**：

```graphql theme={"system"}
{ socialAnalytics(platforms: [INSTAGRAM, TIKTOK]) }
```

而不是 `"instagram"`。服务器会将每个被接受的枚举映射为底层 REST 控制器所需的确切值，通常（但并非总是）是小写字符串。无效的枚举会在操作运行前的 GraphQL 验证阶段被拒绝，因此拼写错误不会让你付出任何代价。

有些参数在不同操作中名称相同，但接受的值不同，因为这些端点确实存在差异。`reviews(platform:)` 只接受 `GMB` 和 `FACEBOOK`，因为只有这两个社交网络有评价。你的客户端自动补全会显示每个操作对应的正确取值。

<h3 id="the-json-scalar">
  JSON 标量
</h3>

少数参数的类型是 `JSON`，而不是某个特定类型。这种情况出现在某个值确实有多种结构，且没有任何单一 GraphQL 类型能够如实描述它的时候：

<ul class="custom-bullets">
  <li><code>explainError(code:)</code> 接受 <code>215</code> 或 <code>"215"</code>，因为客户保存错误代码时两种形式都有。</li>
  <li><code>createPost(input:)</code> 对 <code>post</code> 和 <code>mediaUrls</code> 等字段使用 JSON，这些字段可以是共享值，也可以是按平台区分的对象。</li>
  <li><code>createAutomation(triggers:, actions:)</code> 接受数组，其中的字段取决于每个条目的 <code>type</code>。</li>
  <li><code>boostFacebookPost(interests:)</code> 接受字符串或数字形式的 Meta 兴趣 ID。</li>
</ul>

传入与你在对应 REST 请求体中发送的相同的值。`JSON` 参数并不是漏洞：解析器会在分派之前对其进行验证，因此无效值会返回验证错误，且不会消耗 API 调用。

<h3 id="optional-arguments-and-nulls">
  可选参数与 null
</h3>

对于可选参数以及输入对象中的可选字段，显式的 `null` 会被规范化为省略。当列表类型允许时，列表中的 null 成员会被保留。

<h2 id="reading-responses">
  读取响应
</h2>

大多数操作返回一个包含完整 REST 响应信封的 `JSON` 标量，因此选择根字段时不要带子字段。`createPost` 目前返回类型化的 `PostResult`，因此需要选择它的字段：

```graphql theme={"system"}
mutation {
  createPost(input: {
    post: "Hi"
    platforms: [LINKEDIN]
    idempotencyKey: "linkedin-hi-001"
  }) {
    status
    id
    postIds { platform postUrl }
    errors { platform message code }
  }
}
```

`PostResult` 等类型化响应类型还包含 `raw: JSON!`，其中是完整、未经修改的 REST 响应：

```graphql theme={"system"}
mutation {
  createPost(input: {
    post: "Hi"
    platforms: [LINKEDIN]
    idempotencyKey: "linkedin-hi-001"
  }) {
    status
    raw
  }
}
```

`raw` 会永久保留，其目的是确保 REST 响应中出现的新字段在我们为其补充类型之前，始终可以通过 GraphQL 获取。如果你需要的内容未由类型化字段公开，请请求 `raw`。

<h2 id="uploading-media">
  上传媒体
</h2>

**媒体字节无法通过 GraphQL 请求传输。** GraphQL 请求是一个大小限制在 64 KB 以内的 JSON 文档，因此没有可以接受文件的字段；而将图片以 base64 编码放入查询中，除缩略图外的任何内容都会超出该限制。

受支持的方式完全避开了这个问题，而且无论如何都比通过 API 上传更快，因为你的字节会直接进入存储：

1. 请求一个上传 URL：

   ```graphql theme={"system"}
   mutation { mediaUploadUrl(contentType: "image/jpeg") }
   ```

2. 从返回的 JSON 中读取 `data.mediaUploadUrl.uploadUrl`、`accessUrl` 和 `contentType`。

3. 将你的文件 `PUT` **直接发送到 `uploadUrl`**，而不是 Ayrshare API，并将请求的 `Content-Type` header 设置为返回的 `contentType`。

4. 上传成功后，在 `createPost.input.mediaUrls` 中传入 `accessUrl`：

   ```graphql theme={"system"}
   mutation {
     createPost(input: {
       post: "With a photo"
       platforms: [INSTAGRAM]
       mediaUrls: ["https://the-returned-access-url"]
       idempotencyKey: "instagram-photo-001"
     }) {
       status
       postIds { platform postUrl }
     }
   }
   ```

请将 `uploadUrl` 视为短期有效的写入凭据，不要记录或泄露它。`accessUrl` 是创建帖子时使用的媒体 URL。

你也可以继续使用 [REST 上传端点](/docs/apis/media/upload-media)，并在 GraphQL 中引用生成的 URL。两种接口共享同一个媒体库。

<h2 id="read-next">
  延伸阅读
</h2>

<ul class="custom-bullets">
  <li>[错误](/docs/apis/graphql/errors)：HTTP 状态码、错误结构以及部分成功。</li>
  <li>[限制与计费](/docs/apis/graphql/limits)：查询大小上限以及请求的计数方式。</li>
</ul>
