Tài liệu

API cho nhà phát triển

Cổng API của WitsAGI nói đúng chuẩn OpenAI — SDK bạn đang dùng chỉ cần đổi base_url và api_key, không phải viết lại gì. Mỗi lượt gọi trừ Wits từ ví của chủ khoá, tính theo token thật sau khi sinh xong (phần đặt cọc thừa được hoàn lại).

1. Lấy khoá

  1. Đăng nhập witsagi.com → Cài đặt → API keys → Tạo khoá.
  2. Khoá dạng sk-wits-… chỉ hiện một lần. Chép và cất vào kho bí mật ngay.
  3. Đặt hạn mức token/tháng cho khoá để giới hạn chi phí khi giao cho đối tác thử.
  4. Nạp Wits tại witsagi.com/billing. Xem số dư bất cứ lúc nào: GET /api/v1/balance.

Khoá là bí mật của bạn: đừng nhúng vào ứng dụng chạy trên trình duyệt hay app di động. Gọi từ máy chủ của bạn. Lỡ lộ thì thu hồi ngay trong Cài đặt, khoá chết lập tức.

2. Gọi thử

Điểm cuối: POST https://witsagi.com/api/v1/chat/completions

curl
curl https://witsagi.com/api/v1/chat/completions \
  -H "Authorization: Bearer sk-wits-XXXXXXXXXXXX" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wits-pro-5.5",
    "messages": [
      {"role": "system", "content": "Bạn là trợ lý nghiệp vụ."},
      {"role": "user", "content": "Tóm tắt quy trình nghiệm thu nội bộ trong 5 gạch đầu dòng."}
    ],
    "max_tokens": 1024
  }'
Python · SDK OpenAI
from openai import OpenAI          # SDK OpenAI chuẩn, không cần thư viện riêng

client = OpenAI(
    base_url="https://witsagi.com/api/v1",
    api_key="sk-wits-XXXXXXXXXXXX",
)

r = client.chat.completions.create(
    model="wits-pro-5.5",
    messages=[{"role": "user", "content": "Chào Wits"}],
)
print(r.choices[0].message.content)
print(r.usage)                        # prompt_tokens / completion_tokens / total_tokens
Node · fetch (có xử lý 429)
const res = await fetch('https://witsagi.com/api/v1/chat/completions', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer sk-wits-XXXXXXXXXXXX',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'wits-pro-5.5',
    messages: [{ role: 'user', content: 'Chào Wits' }],
    stream: false,
  }),
})
if (res.status === 429) {
  // Nhịp hoặc hạn mức — chờ đúng số giây trong Retry-After rồi gọi lại.
  const cho = Number(res.headers.get('Retry-After') ?? 5)
  await new Promise((r) => setTimeout(r, cho * 1000))
}
const data = await res.json()
console.log(data.choices[0].message.content, data.wits_charged, data.balance)
Phản hồi
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "model": "wits-pro-5.5",
  "choices": [{ "index": 0, "message": { "role": "assistant", "content": "…" }, "finish_reason": "stop" }],
  "usage": { "prompt_tokens": 128, "completion_tokens": 342, "total_tokens": 470 },
  "wits_charged": 470,
  "balance": 4749530
}

Thêm "stream": true để nhận SSE theo chuẩn OpenAI (data: {...} rồi data: [DONE]). Mẩu chốt có kèm usage, wits_charged và balance.

3. Model

Danh sách hiện hành luôn lấy được bằng GET /api/v1/models. Gửi kèm ảnh theo định dạng multimodal của OpenAI (image_url dạng data-URI) thì Wits đọc ảnh/bản vẽ và bóc số liệu.

4. Nhịp gọi & hạn mức

Mọi phản hồi đều mang X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset; khi bị chặn có thêm Retry-After tính bằng giây. Hãy đọc Remaining để tự giãn nhịp, đừng đợi tới lúc 429.

5. Mã lỗi

Thân lỗi (hình OpenAI)
{
  "error": {
    "message": "Ví Wits của chủ tài khoản không đủ cho yêu cầu này: cần khoảng 1.200 Wits, còn 30 Wits. …",
    "type": "insufficient_quota",
    "code": "insufficient_wits",
    "param": null
  }
}
codeHTTPNghĩaCần làm
invalid_api_key401Thiếu header, sai khoá, hoặc khoá đã thu hồi.Kiểm tra header Authorization: Bearer sk-wits-… · tạo khoá mới trong Cài đặt → Khoá API (hoặc platform.witsagi.com → Khoá API).
invalid_request400Thân yêu cầu không hợp lệ (thiếu messages, sai kiểu).Đối chiếu ví dụ ở trên. messages là mảng, mỗi phần tử có role + content.
model_not_found404Tên model không nằm trong danh sách phục vụ.Gọi GET /api/v1/models để lấy danh sách hiện hành.
rate_limited429Vượt nhịp: 120 yêu cầu/phút hoặc 20 yêu cầu/10 giây.Chờ đúng số giây ghi trong header Retry-After. Xem X-RateLimit-Remaining để giãn nhịp trước.
quota_exceeded429Khoá đã dùng hết HẠN MỨC TOKEN tháng của chính nó.Nhờ chủ tài khoản nâng hạn mức của khoá. Hạn mức tự đặt lại ngày 1 tháng sau.
insufficient_wits402VÍ WITS của chủ tài khoản không đủ (khác hạn mức khoá).Nạp Wits tại witsagi.com/billing. Yêu cầu bị từ chối KHÔNG bị trừ đồng nào.
engine_busy502Engine tạm bận hoặc quá hạn.Thử lại sau vài giây. Wits của yêu cầu hỏng đã được hoàn lại tự động.

Phân biệt hai cái hay bị nhầm: quota_exceeded là khoá hết hạn mức (nâng hạn mức), còn insufficient_wits là ví hết tiền (nạp Wits). Yêu cầu bị từ chối ở cả hai trường hợp đều không bị trừ đồng nào.

6. Tính tiền

Trừ theo token thật: token vào và token ra tính riêng theo bậc model. Trước khi chạy, hệ đặt cọc theo ước lượng xấu nhất; sinh xong thì hoàn lại phần thừa ngay trong cùng lượt gọi. Con số đã trừ nằm ở wits_charged, số dư còn lại ở balance của chính phản hồi đó — không cần gọi thêm để đối soát.

7. Liêm chính dữ liệu

Wits được đặt luật cấm bịa số: mọi con số, điều luật, đơn giá trong câu trả lời phải truy được về kho tri thức đã kiểm chéo hoặc về máy tính tất định, và được dẫn nguồn ngay tại chỗ kèm đường link bấm được. Không có căn cứ thì Wits không nêu như sự thật: phần đó được trình bày là lập luận của Wits hoặc ví dụ minh hoạ có ghi rõ, chứ không đưa một con số ước chừng như số thật. Đây là hành vi cố ý — con số kèm nguồn là con số bạn có thể tin.