Xác thực
Hầu hết các yêu cầu tới AstroWay API đều được xác thực qua header X-Api-Key. Ngoại lệ: 14 endpoint /v1/reference/* (signs, planets, houses, aspects, …) hoạt động công khai không cần key với giới hạn 30 yêu cầu / giờ cho mỗi IP. Nếu yêu cầu được thực hiện bởi server của bạn, gửi header X-AstroWay-Site-URL và giới hạn sẽ tăng lên 300 yêu cầu / giờ cho site: chi tiết.
Đối với tất cả endpoint tính toán /v1/* (chart, synastry, transits, /reports, /tarot, v.v.) - chỉ cần X-Api-Key. Đối với các thao tác người dùng /v1/me/* (GET /me, DELETE /me/account) - Bearer JWT, được cấp qua /v1/auth/login. OAuth/session-cookies không được sử dụng trên API công cộng. Reference-dictionaries /v1/reference/* - không cần key, miễn phí (bảng lookup chuẩn).
Định dạng khóa
Phần tiêu đề “Định dạng khóa”aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_test_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_live_: production, trừ credit từ số dưaw_test_: sandbox, các yêu cầu trả về phản hồi ổn định (hoặc tính toán thực tế tối thiểu), không trừ credit, được đánh dấu riêng trong dashboard- Sau tiền tố: 32 ký tự base62, ngẫu nhiên về mặt mật mã
- Khóa được hiển thị ở dạng nguyên bản chỉ một lần khi tạo. Sau đó trong dashboard - chỉ 4 ký tự đầu và cuối.
Tiêu đề yêu cầu
Phần tiêu đề “Tiêu đề yêu cầu”POST /v1/chart HTTP/1.1Host: api.astroway.infoX-Api-Key: aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRContent-Type: application/jsonBộ sưu tập Postman
Phần tiêu đề “Bộ sưu tập Postman”Nếu bạn thấy Postman tiện hơn curl/SDK - có sẵn một collection với tất cả 771 endpoint, được chia thành 55 thư mục theo các tag OpenAPI, kèm các ví dụ yêu cầu. Auth được cấu hình ở mức collection: bạn chỉ cần chèn key vào biến apiKey một lần, mọi yêu cầu sẽ tự lấy.
- Tài liệu đã xuất bản: documenter.getpostman.com/view/54689779/2sBXqNmy3n
- Không gian làm việc công cộng: postman.com/astroway-info/astroway-api
- Tải JSON: astroway-api.json (≈ 5 MB) - nhập trực tiếp vào Postman hoặc Insomnia
Collection tự động tạo từ OpenAPI spec - được cập nhật mỗi khi deploy.
Tạo và quản lý khóa
Phần tiêu đề “Tạo và quản lý khóa”Qua dashboard:
- api.astroway.info/dashboard/keys
- Có thể có tới 10 khóa hoạt động cho mỗi tài khoản đồng thời
- Mỗi khóa có tên, trường
name(ví dụproduction-backend,ci-tests,local-dev)
Qua API (cho tích hợp tự phục vụ):
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"name": "ci-tests", "mode": "test"}'// Equivalent via @astroway/sdk: aw.client.POST('/keys', { body: { name, mode } })const r = await fetch('https://api.astroway.info/v1/keys', { method: 'POST', headers: { 'X-Api-Key': process.env.ASTROWAY_MASTER_KEY!, 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'ci-tests', mode: 'test' }),});
const { data: created } = await r.json();console.log(created.api_key); // shown once - store it now# Equivalent via `astroway` (PyPI): aw.post('/keys', body={'name': ..., 'mode': ...})import os, requests
r = requests.post( 'https://api.astroway.info/v1/keys', headers={'X-Api-Key': os.environ['ASTROWAY_MASTER_KEY']}, json={'name': 'ci-tests', 'mode': 'test'},)created = r.json()['data']print(created['api_key']) # shown once - store it now<?phpuse GuzzleHttp\Client;
$aw = new Client(['base_uri' => 'https://api.astroway.info/v1/']);$r = $aw->post('keys', [ 'headers' => ['X-Api-Key' => getenv('ASTROWAY_MASTER_KEY')], 'json' => ['name' => 'ci-tests', 'mode' => 'test'],]);
$created = json_decode($r->getBody(), true)['data'];echo $created['api_key']; // shown once - store it nowKhóa cho trình duyệt
Phần tiêu đề “Khóa cho trình duyệt”Khóa tiêu chuẩn server-only: nếu yêu cầu có header Origin hoặc Referer, sẽ nhận 403 ORIGIN_FORBIDDEN. Điều này cố ý, và là cách bắt khóa nếu vô tình để lại trong frontend.
Khi widget hoặc trang có thể gọi API từ trình duyệt, khóa được tạo ngay với chính sách origin. Trường origin_restriction trong POST /v1/keys:
type | Cho phép | Khi dùng |
|---|---|---|
server-only (mặc định) | chỉ các yêu cầu không có Origin và Referer | backend, cron, CI |
public | chỉ các host được liệt kê, và yêu cầu bắt buộc mang origin | widget hoặc trang trên domain của bạn, khóa trong mã nguồn |
allowlist | giống như public | cách viết cũ: vẫn được chấp nhận, nhưng không còn xuất hiện trong openapi.json |
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "name": "site-widget", "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] }, "credits_cap_cycle": 20000, "allowed_endpoints": ["chart", "public/*"] }'Quy tắc khớp, đã kiểm tra trên prod:
- Tối đa 20 host cho mỗi khóa. Scheme (
https://) và cổng bị bỏ qua, không phân biệt chữ hoa/thường. www.được loại bỏ khỏi host đầu vào, vì vậyexample.combao phủ cảwww.example.com. Không cần thêm dạngwww.riêng, nó không thay đổi gì.*.example.combao phủ các subdomain (app.example.com), nhưng không bao gồmexample.com. Apex được liệt kê riêng, như trong ví dụ trên.- Host không có trong danh sách nhận được
403 ORIGIN_NOT_ALLOWEDvới host trong trườngincoming_origin, để thấy dòng nào thiếu. Refererđược tính đồng mức vớiOrigin: trình duyệt gửi nó khi không cóOrigin.
Thay đổi danh sách của khóa đã tạo
Phần tiêu đề “Thay đổi danh sách của khóa đã tạo”PATCH /v1/keys/{id} ghi đè danh sách, không thay đổi khóa. Quyền truy cập giống như POST /v1/keys ở trên; trong dashboard đây là mục “Thay đổi origin” trong menu của khóa.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] } }'Danh sách mới có hiệu lực ngay từ yêu cầu tiếp theo: cache của khóa được xóa khi ghi, không cần chờ một phút. Chuỗi khóa không thay đổi, vì vậy không cần cập nhật lại trang hay backend. Sau POST /v1/keys/{id}/rotate danh sách được lưu, và giá trị cũ của khóa ngừng hoạt động ngay lập tức.
Lớp khóa không thể chỉnh sửa, vì nó được ghi trong chính khóa:
| Thử | Phản hồi |
|---|---|
pk_ chuyển thành server-only | 400: lớp là một phần của khóa, cần thu hồi và tạo mới |
aw_ thêm danh sách domain | 400: khóa trình duyệt là lớp khác, nó được tạo dưới dạng public |
pk_ với danh sách rỗng | 400: khóa không có danh sách sẽ từ chối mọi yêu cầu |
pk_ không có ngân sách hoặc phạm vi (null) | 400: khóa trình duyệt luôn bị giới hạn cả hai, có thể thay đổi nhưng không thể bỏ |
Ngân sách credit cho mỗi khóa
Phần tiêu đề “Ngân sách credit cho mỗi khóa”Credit được chia chung cho toàn bộ tài khoản, vì vậy một khóa có thể tiêu hết chúng. Đối với khóa backend thì bình thường, nhưng đối với khóa trong mã nguồn trang thì không: danh sách domain cho biết từ đâu có thể gọi, nhưng không cho biết chi phí.
credits_cap_cycle trong cùng PATCH /v1/keys/{id} giới hạn chính khóa này:
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"credits_cap_cycle": 5000}'null bỏ giới hạn (ngoại trừ khóa pk_, ngân sách của nó có thể thay đổi nhưng không thể bỏ). 0 có nghĩa là khóa không thể tiêu bất kỳ credit nào: cách để “đỗ” khóa mà không thu hồi. Bộ đếm giống như credit và được đặt lại cùng chu kỳ gói.
Khi khóa đạt tới ngân sách, trả về 429 KEY_BUDGET_EXHAUSTED, ngay cả khi tài khoản còn credit và ngay cả trên gói có overage: ngân sách có thể vượt quá bằng tiền không phải là ngân sách. Khi ngân sách được đặt, mỗi phản hồi sẽ chứa X-Key-Budget-Limit và X-Key-Budget-Remaining.
Phạm vi endpoint
Phần tiêu đề “Phạm vi endpoint”Khóa không có phạm vi sẽ gọi mọi thứ trong gói. allowed_endpoints thu hẹp nó thành danh sách các đường dẫn: cụ thể (chart) hoặc không gian tên (embed/*). Đây là giới hạn thứ ba, độc lập: danh sách domain cho biết từ đâu, ngân sách cho biết bao nhiêu, phạm vi cho biết gì.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"allowed_endpoints": ["embed/*", "public/moon-phase"]}'null bỏ giới hạn (ngoại trừ khóa pk_, phạm vi của nó là bắt buộc). Danh sách rỗng không được chấp nhận: nó sẽ được hiểu cả là “tất cả” và “không gì”. Các đường dẫn được viết tương đối với /v1, không có dấu slash đầu, không phân biệt chữ hoa/thường.
Gọi ngoài danh sách nhận 403 ENDPOINT_NOT_IN_SCOPE, và details sẽ chỉ ra danh sách đó, để không phải đoán. Phạm vi áp dụng cho cả hai lớp khóa và cho /v1/public/* và /v1/embed/* giống như các endpoint còn lại. Các đọc dịch vụ từ nó không được miễn, trái ngược với credit: khóa thu hẹp tới embed/* cũng không thể đọc thống kê của mình. Điều này cố ý, vì khóa trong mã nguồn trang không nên tiết lộ chi phí tài khoản cho người truy cập, nhưng việc quản lý khóa không bị ảnh hưởng: dashboard hoạt động bằng session, không phải bằng khóa.
Thực hành tốt
Phần tiêu đề “Thực hành tốt”1. Đừng đặt khóa server-only vào frontend
Phần tiêu đề “1. Đừng đặt khóa server-only vào frontend”Khóa tiêu chuẩn là bí mật cấp backend. Nếu nó xuất hiện trong JS chạy trên trình duyệt người dùng - nó sẽ hiển thị trong DevTools và bị rò rỉ. Đó là lý do khóa này trả về 403 ORIGIN_FORBIDDEN cho bất kỳ yêu cầu nào có Origin hoặc Referer.
Nếu vẫn cần gọi từ trình duyệt, hãy dùng một khóa riêng, được tạo với origin_restriction.type: "public": khóa cho trình duyệt. Khóa này có tiền tố pk_, cũng sẽ hiển thị trong DevTools, và đó là mục đích - giá trị của nó bị giới hạn bởi danh sách domain của bạn, và yêu cầu không có origin sẽ bị từ chối.
Đúng: backend của bạn giữ khóa, frontend gọi vào backend của bạn, backend của bạn gọi AstroWay API.
Sai:
// DO NOT DO THISfetch('https://api.astroway.info/v1/chart', { headers: { 'X-Api-Key': 'aw_live_...' }, // visible in browser});2. Biến môi trường, không hardcode
Phần tiêu đề “2. Biến môi trường, không hardcode”# .env (in .gitignore)ASTROWAY_API_KEY=aw_live_...// in codeconst key = process.env.ASTROWAY_API_KEY;if (!key) throw new Error('ASTROWAY_API_KEY is not set');3. Khóa riêng cho các môi trường khác nhau
Phần tiêu đề “3. Khóa riêng cho các môi trường khác nhau”production-backend: productionstaging-backend: stagingci-tests: pipeline CI/CDlocal-dev-maksym: phát triển cục bộ của mỗi nhà phát triển
Nếu một khóa bị xâm phạm - thu hồi chỉ khóa đó, các khóa còn lại vẫn hoạt động.
4. Quay vòng
Phần tiêu đề “4. Quay vòng”Tần suất đề xuất - một lần mỗi 90 ngày. Hoặc ngay lập tức nếu nghi ngờ rò rỉ.
Quay vòng không downtime:
- Tạo khóa mới với cùng
name+-v2 - Triển khai nó trong production (song song với khóa cũ)
- Đảm bảo usage chuyển sang khóa mới (dashboard)
- Thu hồi khóa cũ
5. Giám sát usage
Phần tiêu đề “5. Giám sát usage”Dashboard hiển thị yêu cầu theo từng khóa. Nếu bất ngờ một khóa tăng lên 10× số yêu cầu so với bình thường - đó là tín hiệu cần kiểm tra.
Bạn có thể đặt cảnh báo: Settings → Notifications → Alert when daily credits > X.
Lỗi xác thực
Phần tiêu đề “Lỗi xác thực”| Mã | Ý nghĩa |
|---|---|
401 Unauthorized | Header X-Api-Key thiếu hoặc khóa không hợp lệ |
403 Forbidden | Khóa hợp lệ, nhưng không có scope cho hành động này (ví dụ, khóa thường cố gắng quản lý các khóa khác) |
403 PUBLISHABLE_KEY_UNBOUNDED | Khóa pk_ thiếu ngân sách credits_cap_cycle hoặc thiếu phạm vi allowed_endpoints: hãy đặt cả hai trong cài đặt khóa |
402 Payment Required | Credit đã hết (trên gói Free) hoặc thuê bao không hoạt động |
429 Too Many Requests | Vượt quá rate limit (10/60/300 req/min tùy theo gói) |
Ví dụ 401:
{ "error": { "code": "invalid_api_key", "message": "The API key provided is invalid or has been revoked.", "request_id": "8aec43e9bc749b37e998a489bbad1757" }}Chế độ Sandbox
Phần tiêu đề “Chế độ Sandbox”Khóa có tiền tố aw_test_ hoạt động trong sandbox:
- Không trừ credit
- Trả về phản hồi ổn định hoặc tính toán thực tế tối thiểu
- Không ảnh hưởng tới thống kê production
- Các endpoint khả dụng: giống như bình thường
Có ích cho CI/CD, kiểm thử e2e và phát triển cục bộ. Được tạo qua dashboard chỉ một cú nhấp.
Tiếp theo
Phần tiêu đề “Tiếp theo”- Credit và giới hạn: như hoạt động billing và rate limiting
- Lỗi: danh sách đầy đủ các error-code