
# Xác thực

Mọi yêu cầu API đều phải mang theo khóa API của bạn để <span data-t="appName">Your AI Connector</span> biết đó là bạn và tài khoản nào cần được thực hiện. Bạn có thể gửi khóa theo bốn cách khác nhau — tất cả đều hoạt động trên mọi điểm cuối chấp nhận xác thực bằng khóa API, vì vậy hãy chọn cách phù hợp với thiết lập của bạn.

Truy cập API là một tính năng trả phí. Nếu gói của bạn không bao gồm tính năng này, các yêu cầu sẽ bị từ chối với `403` ngay cả khi bản thân khóa đó hợp lệ — xem [Cổng tính năng trả phí](#the-paid-feature-gate) bên dưới. Để tạo khóa, hãy xem [Truy cập API](../integrations/api-access.md).

> **Chỉ HTTPS.** Tất cả các yêu cầu phải sử dụng kết nối bảo mật. Các yêu cầu HTTP thông thường sẽ bị từ chối trước khi quá trình xác thực diễn ra.

---

## Sơ lược về bốn phương thức

| Phương thức | Trình vận chuyển | Khi nào nên sử dụng |
|---|---|---|
| Tham số truy vấn | `?apiKey=YOUR_API_KEY` | Kiểm tra nhanh và URL trình duyệt |
| Tiêu đề | `X-API-Key: YOUR_API_KEY` | Tích hợp sản xuất |
| Tiêu đề Bearer | `Authorization: Bearer YOUR_API_KEY` | Tích hợp sản xuất |
| Mã thông báo ID Firebase | `Authorization: Bearer <ID token>` | Chỉ dành cho phiên ứng dụng bên thứ nhất |

Khi có nhiều hơn một phương thức, tham số truy vấn sẽ được ưu tiên, sau đó đến tiêu đề `X-API-Key`, và cuối cùng là mã thông báo bearer. Trong thực tế, bạn chỉ nên gửi một phương thức.

---

## 1. Tham số truy vấn — `?apiKey=`

Thêm khóa của bạn vào cuối địa chỉ web. Đây là hình thức đơn giản nhất và luôn hoạt động, giúp nó trở nên lý tưởng cho các bài kiểm tra nhanh, tập lệnh và bất kỳ công cụ cũ nào.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY");
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts",
    params={"apiKey": "YOUR_API_KEY"},
)
data = res.json()
```

> **Lưu ý:** Địa chỉ web sẽ xuất hiện trong lịch sử trình duyệt, nhật ký truy cập máy chủ và nhật ký proxy. Đối với bất kỳ mục đích nào ngoài việc kiểm tra nhanh, hãy ưu tiên một trong các phương thức tiêu đề bên dưới để khóa của bạn không bị ghi vào đĩa ở dạng văn bản thuần túy.

---

## 2. Tiêu đề `X-API-Key`

Gửi khóa trong một tiêu đề chuyên dụng. Cách này giúp khóa không hiển thị trong URL và là lựa chọn được khuyến nghị cho môi trường sản xuất.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/contacts" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/contacts", {
  headers: {
    "X-API-Key": "YOUR_API_KEY",
  },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

---

## 3. Tiêu đề `Authorization: Bearer`

Bạn cũng có thể truyền khóa dưới dạng mã thông báo bearer tiêu chuẩn. Cách này rất hữu ích khi ứng dụng khách hoặc framework HTTP của bạn đã có sẵn hỗ trợ cho các tiêu đề `Authorization`.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/contacts" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/contacts", {
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
  },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/contacts",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
data = res.json()
```

API sẽ tự động phân biệt khóa API của bạn với mã thông báo đăng nhập, vì vậy phương thức này hoạt động chính xác giống như `X-API-Key`.

---

## 4. Mã thông báo ID Firebase (chỉ dành cho bên thứ nhất)

Nếu bạn đang xây dựng một ứng dụng bên thứ nhất cho phép người dùng đăng nhập thông qua quy trình đăng nhập của chính <span data-t="appName">Your AI Connector</span>, bạn có thể truyền mã thông báo ID Firebase của người dùng đã đăng nhập đó dưới dạng mã thông báo bearer thay vì khóa API:

```
Authorization: Bearer <Firebase ID token>
```

Mã thông báo được xác minh trên mỗi yêu cầu và ánh xạ tới tài khoản đã đăng nhập. **Phương thức này chỉ dành cho các phiên ứng dụng bên thứ nhất** — bạn không thể tạo các mã thông báo này từ một tích hợp bên ngoài và không có cách nào để lấy được mã thông báo nếu không thông qua quy trình đăng nhập ứng dụng thông thường. Đối với các tích hợp máy chủ với máy chủ và bên thứ ba, hãy sử dụng khóa API (các phương thức 1–3).

---

## Khi nào nên sử dụng phương thức nào

- **Kiểm thử nhanh và tập lệnh dùng một lần** → tham số truy vấn (`?apiKey=`). Gõ nhanh nhất, hoạt động trên trình duyệt.
- **Tích hợp sản xuất và các lệnh gọi máy chủ với máy chủ** → `X-API-Key` hoặc `Authorization: Bearer YOUR_API_KEY`. Giữ cho khóa không bị lộ trong URL và nhật ký.
- **Ứng dụng bên thứ nhất với người dùng <span data-t="appName">Your AI Connector</span> đã đăng nhập** → `Authorization: Bearer <Firebase ID token>`.

---

## Phạm vi khóa

Tài khoản của bạn có một **khóa API chính** — khóa nằm trong mục **Cài đặt → Tích hợp → Khóa API**. Khóa này có toàn quyền truy cập vào mọi chức năng của tài khoản.

Bạn cũng có thể tạo thêm các **khóa có phạm vi giới hạn (scoped keys)**: các khóa được đặt tên chỉ có quyền truy cập vào các phần của API mà bạn chọn, ví dụ như khóa chỉ đọc giới hạn cho Analytics để dùng trong bảng điều khiển báo cáo. Khóa có phạm vi giới hạn được gửi giống hệt như khóa chính (bất kỳ phương thức nào trong 1–3 ở trên), nhưng nó sẽ được kiểm tra dựa trên các quyền riêng của nó trong mỗi yêu cầu:

- **Bên ngoài các khu vực được cho phép, khóa sẽ bị từ chối.** Một yêu cầu ghi bằng khóa chỉ đọc, hoặc một lệnh gọi đến phần không được cấp quyền, sẽ trả về `403` — `key_read_only` hoặc `key_scope_denied` trong trường `error_code`. Việc kiểm tra được thực hiện nghiêm ngặt một cách có chủ đích: bất kỳ thứ gì không nằm rõ ràng trong các khu vực được cho phép của khóa sẽ bị từ chối thay vì được thông qua, vì vậy nếu bạn thấy một trong những `403` đó, nghĩa là khóa đơn giản là không bao gồm điểm cuối (endpoint) đó.
- **Nó có hạn mức giới hạn tốc độ (rate-limit) riêng.** Khóa có phạm vi giới hạn được tính riêng biệt với khóa chính của bạn, vì vậy một bảng điều khiển bận rộn sử dụng khóa có phạm vi giới hạn sẽ không làm tiêu tốn hạn mức mà các tích hợp khác của bạn đang phụ thuộc vào. Bạn chọn hạn mức mỗi phút đó khi tạo khóa.
- **Nó không thể quản lý các khóa API.** Chỉ chủ sở hữu tài khoản — khi đã đăng nhập hoặc sử dụng khóa chính — mới có thể liệt kê, tạo, chỉnh sửa, xoay vòng hoặc thu hồi các khóa. Một khóa có phạm vi giới hạn không bao giờ có thể tự tạo ra một khóa có quyền hạn rộng hơn.

Xem [Khóa API](api-keys.md) để biết cách tạo, chỉnh sửa và thu hồi các khóa có phạm vi giới hạn.

---

## Cổng tính năng trả phí

Truy cập API là một tính năng trả phí. Khi gói dịch vụ của bạn không bao gồm tính năng này, một yêu cầu với khóa hợp lệ khác sẽ bị từ chối kèm theo `403`:

```json
{
  "success": false,
  "error_code": 403,
  "error": "This action requires the \"api_access\" feature, which is not enabled for this account."
}
```

If you see this, check your plan or contact [<span data-t="supportEmail">hi@youraiconnector.com</span>](mailto:hi@youraiconnector.com). A missing or wrong key returns `401` instead:

```json
{
  "success": false,
  "error_code": 401,
  "error": "Invalid API key"
}
```

---

## Giữ an toàn cho khóa của bạn

- **Hãy coi khóa như mật khẩu.** Khóa chính của bạn cấp toàn quyền truy cập vào tài khoản của bạn. Nếu bạn cần cung cấp khóa cho một công cụ hoặc một người chỉ cần một phần quyền hạn, hãy tạo khóa có phạm vi giới hạn thay thế — xem [Phạm vi khóa](#key-scopes).
- **Giữ khóa ở phía máy chủ.** Không bao giờ nhúng khóa vào JavaScript của trình duyệt, gói ứng dụng di động hoặc bất kỳ mã nào mà người dùng cuối có thể đọc được.
- **Lưu trữ khóa trong trình quản lý bí mật** hoặc cấu hình phía máy chủ, không lưu trong hệ thống quản lý mã nguồn.
- **Xoay vòng khóa nếu bị lộ.** Tạo khóa mới từ bảng điều khiển hoặc gọi `POST https://api.youraiconnector.com/v1/api-keys/rotate` — hành động này sẽ vô hiệu hóa khóa cũ ngay lập tức. Xem [Khóa API](api-keys.md).
- **Luôn sử dụng HTTPS** để khóa được mã hóa trong quá trình truyền tải.

---

## Các bước tiếp theo

- [Bắt đầu](getting-started.md) — yêu cầu đầu tiên của bạn và các hướng dẫn về tài nguyên.
- [Lỗi & Phân trang](errors-and-pagination.md) — xử lý lỗi và phân trang kết quả.
- [Khóa API](api-keys.md) — thay đổi, thu hồi và kiểm tra mức sử dụng khóa của bạn.
