> ## 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.

# Sử dụng GraphQL API

> Tìm thao tác, hiểu các kiểu đối số và enum, tạo bài đăng và tải media lên thông qua Ayrshare GraphQL API.

<h2 id="finding-an-operation">
  Tìm một thao tác
</h2>

Schema là nguồn chính xác cho tập con GraphQL được hỗ trợ: các gốc thao tác, tên, đối số, kiểu input và giá trị enum. Phần mô tả cung cấp hướng dẫn sử dụng, và [GraphQL Explorer](https://app.ayrshare.com/graphql-explorer) hiển thị cả hai. Đối với các khả năng chỉ có trên REST, hãy dùng [tài liệu tham khảo REST API](/docs/apis/overview).

Tên thao tác đặt theo các endpoint REST mà chúng gọi tới, ở dạng camelCase. `GET /history` là `postHistory`, `GET /analytics/social` là `socialAnalytics`, `POST /post` là `createPost`.

<h2 id="queries-read-mutations-write">
  Query để đọc, mutation để ghi
</h2>

Query là các thao tác đọc và xác thực không thay đổi gì ở phía chúng tôi. Mutation xuất bản hoặc thay đổi trạng thái, khởi chạy công việc, hoặc gửi email. Cả HTTP verb của REST lẫn chi phí của một lệnh gọi đều không quyết định gốc:

<ul class="custom-bullets">
  <li><code>validatePost</code> kiểm tra một bài đăng mà không xuất bản nó.</li>
  <li><code>validateMedia</code> kiểm tra xem một URL media có truy cập được không.</li>
  <li><code>generatePost</code> là một query vì không có gì thay đổi ở phía chúng tôi. Nó vẫn được tính là một lệnh gọi API và trả về văn bản khác nhau mỗi lần, vì vậy hãy đảm bảo bộ nhớ đệm phía client hoặc cơ chế tự động refetch không lặp lại nó mà bạn không hay biết.</li>
  <li><code>mediaUploadUrl</code> là một mutation vì nó tạo một URL tải lên cho tài khoản của bạn.</li>
  <li><code>linkAnalytics</code> là một mutation vì nó có thể yêu cầu một báo cáo gửi qua email.</li>
  <li><code>userBatch</code> là một mutation vì nó khởi chạy một tác vụ xuất dữ liệu.</li>
</ul>

Hãy dùng Explorer hoặc schema để xác nhận gốc của từng thao tác được hỗ trợ.

<h2 id="creating-a-post">
  Tạo bài đăng
</h2>

`createPost` nhận một đối số `input` duy nhất, vì vậy toàn bộ bài đăng là một object:

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

Input phản ánh [endpoint đăng bài REST](/docs/apis/post/post) đã được tài liệu hóa, bao gồm các object tùy chọn theo từng mạng xã hội và các dạng REST chấp nhận nhiều hơn một cấu trúc JSON:

```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 }
  }
}
```

Một bài đăng có thể thành công trên một mạng xã hội và thất bại trên mạng khác. Đó không phải là request thất bại — xem [Lỗi](/docs/apis/graphql/errors#partial-success-on-multi-network-posts).

<h2 id="argument-types">
  Kiểu đối số
</h2>

Hầu hết đối số là chuỗi, số và boolean thông thường. Có ba trường hợp đáng lưu ý.

<h3 id="enums">
  Enum
</h3>

Nhiều đối số chuỗi có tập giá trị hỗ trợ cố định là enum GraphQL, được viết **không có dấu ngoặc kép và in hoa**:

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

Không phải `"instagram"`. Server ánh xạ mỗi enum được chấp nhận sang đúng giá trị mà controller REST bên dưới mong đợi — thường, nhưng không phải luôn luôn, là một chuỗi chữ thường. Một enum không hợp lệ sẽ bị từ chối trong quá trình xác thực GraphQL trước khi thao tác chạy, vì vậy một lỗi đánh máy không tốn gì của bạn.

Một số đối số có cùng tên giữa các thao tác nhưng chấp nhận các giá trị khác nhau, vì các endpoint thực sự khác nhau. `reviews(platform:)` chỉ chấp nhận `GMB` và `FACEBOOK`, vì đó là những mạng xã hội duy nhất có đánh giá. Tính năng tự động hoàn thành của client sẽ hiển thị đúng tập giá trị cho từng thao tác.

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

Một vài đối số có kiểu `JSON` thay vì một kiểu cụ thể. Điều này xảy ra khi một giá trị thực sự có nhiều hơn một cấu trúc và không có kiểu GraphQL đơn lẻ nào có thể mô tả chính xác nó:

<ul class="custom-bullets">
  <li><code>explainError(code:)</code> chấp nhận <code>215</code> hoặc <code>"215"</code>, vì khách hàng lưu mã lỗi ở cả hai dạng.</li>
  <li><code>createPost(input:)</code> dùng JSON cho các trường như <code>post</code> và <code>mediaUrls</code>, vốn có thể là giá trị dùng chung hoặc object theo từng nền tảng.</li>
  <li><code>createAutomation(triggers:, actions:)</code> nhận các mảng mà trường của chúng phụ thuộc vào <code>type</code> của từng phần tử.</li>
  <li><code>boostFacebookPost(interests:)</code> chấp nhận id sở thích của Meta dưới dạng chuỗi hoặc số.</li>
</ul>

Hãy truyền cùng giá trị mà bạn sẽ gửi trong body REST tương ứng. Một đối số `JSON` không phải là lỗ hổng: resolver xác thực nó trước khi gửi đi, vì vậy một giá trị không hợp lệ sẽ trả về lỗi xác thực và không tiêu tốn lệnh gọi API nào.

<h3 id="optional-arguments-and-nulls">
  Đối số tùy chọn và null
</h3>

Đối với các đối số tùy chọn và các trường tùy chọn bên trong input object, `null` tường minh được chuẩn hóa thành bỏ qua. Các phần tử null bên trong danh sách được giữ nguyên khi kiểu danh sách cho phép.

<h2 id="reading-responses">
  Đọc phản hồi
</h2>

Hầu hết các thao tác trả về một scalar `JSON` chứa toàn bộ envelope phản hồi REST, vì vậy hãy chọn trường gốc mà không có trường con. `createPost` hiện trả về `PostResult` có kiểu, vì vậy hãy chọn các trường của nó:

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

Các kiểu phản hồi có kiểu như `PostResult` cũng bao gồm `raw: JSON!`, chứa toàn bộ phản hồi REST chưa được chỉnh sửa:

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

`raw` là cố định và tồn tại để một trường mới xuất hiện trong phản hồi REST không bao giờ bị không truy cập được từ GraphQL trong khi chúng tôi cập nhật kiểu cho nó. Nếu bạn cần thứ gì đó mà các trường có kiểu không cung cấp, hãy yêu cầu `raw`.

<h2 id="uploading-media">
  Tải media lên
</h2>

**Dữ liệu byte của media không thể truyền qua một request GraphQL.** Một request GraphQL là một tài liệu JSON duy nhất có giới hạn 64 KB, vì vậy không có trường nào chấp nhận tệp, và việc mã hóa một hình ảnh dưới dạng base64 bên trong truy vấn sẽ vượt quá giới hạn đó với bất cứ thứ gì lớn hơn một ảnh thu nhỏ.

Cách được hỗ trợ tránh hoàn toàn vấn đề này, và dù sao cũng nhanh hơn việc tải lên thông qua một API, vì dữ liệu của bạn đi thẳng vào bộ lưu trữ:

1. Yêu cầu một URL tải lên:

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

2. Đọc `data.mediaUploadUrl.uploadUrl`, `accessUrl` và `contentType` từ JSON được trả về.

3. `PUT` tệp của bạn **trực tiếp đến `uploadUrl`**, không phải đến Ayrshare API, đặt header `Content-Type` của request thành `contentType` được trả về.

4. Sau khi tải lên thành công, truyền `accessUrl` vào `createPost.input.mediaUrls`:

   ```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 }
     }
   }
   ```

Hãy coi `uploadUrl` là một thông tin xác thực ghi có thời hạn ngắn và không ghi log hoặc để lộ nó. `accessUrl` là URL media được dùng khi tạo bài đăng.

Bạn cũng có thể tiếp tục sử dụng [các endpoint tải lên REST](/docs/apis/media/upload-media) và tham chiếu các URL thu được từ GraphQL. Hai giao diện dùng chung cùng một thư viện media.

<h2 id="read-next">
  Đọc tiếp
</h2>

<ul class="custom-bullets">
  <li>[Lỗi](/docs/apis/graphql/errors) — mã trạng thái HTTP, cấu trúc lỗi và thành công một phần.</li>
  <li>[Giới hạn và Tính phí](/docs/apis/graphql/limits) — giới hạn kích thước truy vấn và cách tính số request.</li>
</ul>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.