# Xác thực

Mọi lệnh gọi chạy mô hình hoặc đọc yêu cầu của bạn đều cần khóa API. Danh mục (`GET /models`,
`GET /categories`), `POST /quote` và tài liệu OpenAPI là công khai.

## Khóa API

Tạo và thu hồi khóa tại [https://doitong.com/developers/dashboard#keys](https://doitong.com/developers/dashboard#keys). Khóa có dạng
`doitong_` theo sau là 64 ký tự hệ thập lục phân và chỉ được hiển thị một lần khi bạn tạo. Gửi khóa trong tiêu đề
`Authorization`:

```bash
curl https://api.doitong.com/v1/account -H "Authorization: Bearer $DOITONG_API_KEY"
```

`X-API-Key: <key>` cũng hoạt động.

> [!WARNING]
> Giữ khóa trên máy chủ của bạn: bất kỳ ai có khóa đều có thể sử dụng số tín dụng API mà khóa được phép sử dụng. Nếu khóa bị lộ,
> hãy thu hồi khóa và tạo khóa mới.

Yêu cầu không có khóa nhận `401` với mã `missing_api_key`; khóa không xác định, đã thu hồi hoặc hết hạn cũng nhận `401`.

## Phạm vi

Mỗi khóa có các phạm vi. API mô hình kiểm tra các phạm vi sau:

| Hành động | Phạm vi cần thiết |
|---|---|
| Chạy mô hình, hủy yêu cầu, xóa tệp của yêu cầu, thay đổi cài đặt lưu trữ | `models:run` (các khóa có `images:create` hoặc `videos:create` cũ hơn cũng hoạt động) |
| Tạo URL tải lên | `models:run` hoặc `media:upload` |
| Đọc yêu cầu, tài khoản | `models:read` (khóa có thể chạy mô hình cũng có thể đọc) |

Khóa mới mặc định có `models:read` và `models:run`. Lệnh gọi không có phạm vi phù hợp nhận `403` với mã
`insufficient_scope`.

## Ngân sách tín dụng

Một khóa có thể có ngân sách riêng bằng tín dụng API (1.000 tín dụng API = 1 $), do chủ tài khoản đặt: ngân sách tổng, ngân sách
hằng ngày (24 giờ qua), hoặc cả hai. Trước khi tính phí một lần chạy, chi phí được kiểm tra so với số khóa đã chi qua API này
(sau khi trừ tiền hoàn). Một lần chạy vượt quá ngân sách sẽ bị từ chối với `402 budget_exceeded` và không bị tính phí.

> [!IMPORTANT]
> Từ chối do ngân sách là quyết định cuối cùng: thử lại sẽ không có tác dụng cho đến khi chủ sở hữu tăng ngân sách.

 Khóa không có ngân sách có thể
chi tối đa bằng số dư API. Riêng một lần chạy mà số dư API không đủ chi trả sẽ nhận `402 insufficient_credits`
kèm `top_up_url`.

`GET https://api.doitong.com/v1/account` hiển thị số dư API và ngân sách còn lại của khóa (đều tính bằng tín dụng API):

```json 200 OK · tài khoản
{
  "object": "account",
  "credits": 125000,
  "balance": { "credits": 125000, "usd": "125.00" },
  "top_up_url": "https://doitong.com/developers/dashboard#balance",
  "key": {
    "name": "Production server",
    "prefix": "doitong_3fa9c1e...",
    "scopes": ["models:read", "models:run"],
    "budget_remaining": 50000,
    "rate_limit": 3600,
    "rate_limit_remaining": 3571
  },
  "webhook_signing_secret": "whsec_..."
}
```

`budget_remaining` là `null` khi khóa không có ngân sách riêng.

## Giới hạn tốc độ

Mỗi khóa có thể thực hiện 3600 yêu cầu mỗi giờ, trừ khi giới hạn được đặt khác đi. Mọi phản hồi đã xác thực đều chứa
trạng thái hiện tại:

| Header | Ý nghĩa |
|---|---|
| `X-RateLimit-Limit` | Số yêu cầu được phép trong cửa sổ hiện tại |
| `X-RateLimit-Remaining` | Số yêu cầu còn lại trong cửa sổ hiện tại |
| `X-RateLimit-Reset` | Thời điểm Unix khi cửa sổ được đặt lại |

Khi vượt quá giới hạn, bạn nhận `429` cùng tiêu đề `Retry-After` (giây). Thăm dò dài với `?wait=` được tính là một yêu cầu
mỗi lần gọi, vì vậy chờ sẽ tiết kiệm hơn thăm dò nhanh.

Ngoài ra, mỗi tài khoản có giới hạn 10 yêu cầu đang xử lý (`queued` hoặc `running`). Bắt đầu thêm một yêu cầu sẽ trả về
`429 too_many_inflight`; hãy bắt đầu lại sau khi một yêu cầu hoàn tất.
