POSThttps://api.aihubproduction.com/v1/ielts/speaking/grading-json

Chấm câu trả lời bằng URL audio

Dạng dự phòng khi không thể tải audio lên: nhận URL audio đã ký thay vì tệp tải lên.

Request

FieldTypeGiá trị mẫuBắt buộcMô tả
audio_urlstringhttps://s3.wispace.app/ielts-task1/speaking-answers/part-1/do-you-enjoy-living-in-your-city-or-hometown.webmBẮT BUỘCURL HTTPS trên đúng host s3.wispace.app, dài tối đa 2.048 ký tự, có thể kèm query cho signed object URL. AIHUB kiểm tra URL nhưng không tải — nhà cung cấp tự tải và không theo redirect.
partinteger1BẮT BUỘCPart của bài Speaking: 1, 2 hoặc 3.
question_idstringp1_do-you-enjoy-living-in-your-city-or-hometownBẮT BUỘCMã câu hỏi lấy từ endpoint lấy câu hỏi; thay bằng câu hỏi bạn sắp trả lời.
prompt_textstringDo you enjoy living in your city or hometown?tuỳ chọnNội dung câu hỏi, dùng để đánh giá độ liên quan.
test_typestringPracticetuỳ chọnChỉ nhận Practice hoặc Full-test. Bỏ trống thì AIHUB dùng Practice.
test_codestringielts-practice-01tuỳ chọnMã chung cho các câu hỏi thuộc cùng một bài kiểm tra đầy đủ.
transcriptstringI live in a small town.tuỳ chọnTranscript có sẵn, dùng khi nhà cung cấp hỗ trợ bỏ qua bước chuyển giọng nói thành chữ.

Response

Envelope { data, meta } của AIHUB. data khớp hợp đồng chấm Speaking: scorability cho biết lượt nói có chấm được không, estimated_band gồm 5 tiêu chí mỗi tiêu chí là số chẵn hoặc nửa từ 0 đến 9, transcript cho nội dung đã nghe kèm số từ và thời lượng, relevance cho mức độ đúng chủ đề, fluency_metrics cho nhịp nói và ngừng, pronunciation_detail cho chất lượng từng từ và âm, language_analysis cho lỗi ngữ pháp cùng nâng cấp từ vựng, và feedback cho tóm tắt cùng kế hoạch cải thiện. meta cho request_id để báo hỗ trợ, service và operation.

Lưu ý

  • Endpoint này không có idempotent replay — header Idempotency-Key, nếu bạn gửi, bị bỏ qua. Chạy lại cùng một lệnh sẽ tạo một lần chấm mới và tính phí thêm.
  • audio_url chỉ được trỏ tới đúng host s3.wispace.app và scheme https. AIHUB từ chối thông tin đăng nhập nhúng trong URL, fragment, host hoặc cổng khác trước khi gọi dịch vụ.
  • AIHUB không theo redirect. Nếu object URL hết hạn giữa chừng, lượt chấm sẽ thất bại ở phía dịch vụ.
  • Các giá trị trong ví dụ request và response là minh hoạ để bạn thấy hình dạng dữ liệu, không phải traffic thật của AIHUB — đặc biệt là band và điểm phát âm.
  • Request vượt 256 KB trả về 413 PAYLOAD_TOO_LARGE. Trường lạ trong request bị từ chối chứ không bị bỏ qua.
  • Ngân sách 30 giây của gateway là trần của phía server — đặt timeout phía client tối thiểu 60 giây.
# Hai biến dưới là ví dụ — thay bằng giá trị thật, và chỉ chạy trên server của bạn.
AIHUB_API_KEY="aihub_sk_..."            # API key của Organization, có scope speaking.grade
AIHUB_USER_IDENTITY="$SIGNED_USER_ASSERTION"   # Organization có Identity configuration đang hoạt động
# AIHUB_USER_IDENTITY="student_456"     # thay bằng Declared User ID nếu Organization chưa có Identity configuration đang hoạt động

curl -X POST 'https://api.aihubproduction.com/v1/ielts/speaking/grading-json' \
  -H "X-API-Key: $AIHUB_API_KEY" \
  -H "X-User-Identity: $AIHUB_USER_IDENTITY" \
  -H "Content-Type: application/json" \
  -d '{
  "audio_url": "https://s3.wispace.app/ielts-task1/speaking-answers/part-1/do-you-enjoy-living-in-your-city-or-hometown.webm",
  "part": 1,
  "question_id": "p1_do-you-enjoy-living-in-your-city-or-hometown",
  "prompt_text": "Do you enjoy living in your city or hometown?",
  "test_type": "Practice"
}'

Lỗi thường gặp

18 mã dưới đây áp dụng cho hai endpoint chấm Speaking. Mã IDEMPOTENCY_CONFLICT của Writing không có ở đây vì endpoint chấm không có idempotent replay. Mọi lỗi trả về cùng một envelope { error: { code, message, request_id, retryable, retry_after_ms? } }. Rẽ nhánh theo code chứ không theo message, vì message có thể đổi câu chữ.

Chính sách retry
  • Chỉ tự động retry khi retryable là true. Không retry theo mặc định chỉ vì gặp 5xx.
  • Dùng exponential backoff có jitter — ngẫu nhiên từ 0 tới trần, không dùng độ trễ cố định, vì nhiều client retry đúng nhịp sẽ làm dịch vụ lại sập ngay khi nó vừa hồi phục.
  • Giới hạn 2–3 lần thử.
  • Riêng Speaking: không retry mù quáng. Vì endpoint chấm không có idempotent replay, mỗi lần thử lại là một lần chấm mới bị tính phí.
400INVALID_REQUESTRequest không hợp lệ

Field vượt quy tắc, hoặc có field lạ trong request. Trường lạ bị từ chối chứ không bị bỏ qua.

{
  "error": {
    "code": "INVALID_REQUEST",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
401UNAUTHORIZEDAPI key không hợp lệ

Thiếu key, key không tồn tại, đã thu hồi, hoặc đã hết hạn.

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
401USER_IDENTITY_REQUIREDThiếu User Identity

Gọi endpoint user-scoped mà không gửi X-User-Identity.

{
  "error": {
    "code": "USER_IDENTITY_REQUIRED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
401INVALID_USER_IDENTITYUser Identity không hợp lệ

Declared User ID vi phạm quy tắc, hoặc Signed User Assertion không vượt qua kiểm chữ ký.

{
  "error": {
    "code": "INVALID_USER_IDENTITY",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
403FORBIDDENKey thiếu scope

API key không có scope speaking.grade cho thao tác này.

{
  "error": {
    "code": "FORBIDDEN",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
403ENVIRONMENT_NOT_ALLOWEDSai Environment

API key không hợp lệ cho Environment của request này.

{
  "error": {
    "code": "ENVIRONMENT_NOT_ALLOWED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
404NOT_FOUNDKhông có route

Sai path hoặc sai method. Lưu ý dạng chấm có hai path khác nhau.

{
  "error": {
    "code": "NOT_FOUND",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
413PAYLOAD_TOO_LARGERequest quá lớn

Body vượt trần của thao tác: 26 MiB cho request multipart, 256 KB cho JSON-by-URL.

{
  "error": {
    "code": "PAYLOAD_TOO_LARGE",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
429RATE_LIMITEDVượt rate limit

Quá nhiều request mỗi phút. Nghỉ đúng retry_after_ms rồi thử lại.

{
  "error": {
    "code": "RATE_LIMITED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true,
    "retry_after_ms": 2000
  }
}
429CONCURRENCY_LIMITVượt giới hạn chạy song song

Quá nhiều request đang chạy cùng lúc. Giảm số request song song; thử lại sau khoảng 500 ms.

{
  "error": {
    "code": "CONCURRENCY_LIMIT",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true,
    "retry_after_ms": 500
  }
}
429QUOTA_EXCEEDEDHết hạn mức tháng

Đã dùng hết quota tháng. Chờ kỳ reset hoặc nâng cấp.

{
  "error": {
    "code": "QUOTA_EXCEEDED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true
  }
}
500INTERNAL_ERRORLỗi phía AIHUB

Lỗi ngoài dự kiến. Thử lại sau và báo kèm request_id nếu vẫn lỗi.

{
  "error": {
    "code": "INTERNAL_ERROR",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true
  }
}
502AI_SERVICE_ERRORLỗi khi chấm bài

Yêu cầu không hoàn tất. Thử lại sau nếu retryable là true.

{
  "error": {
    "code": "AI_SERVICE_ERROR",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true
  }
}
502AI_SERVICE_CONTRACT_VIOLATIONKết quả không đúng định dạng

Không retry. Báo lại kèm request_id — đây là lỗi phía chúng tôi, không phải phía bạn.

{
  "error": {
    "code": "AI_SERVICE_CONTRACT_VIOLATION",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
503AI_SERVICE_THROTTLEDYêu cầu đang quá tải

Lùi rồi thử lại; lỗi này không kèm retry_after_ms.

{
  "error": {
    "code": "AI_SERVICE_THROTTLED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true
  }
}
503AI_SERVICE_UNAVAILABLETạm thời chưa thể xử lý

Thử lại với backoff.

{
  "error": {
    "code": "AI_SERVICE_UNAVAILABLE",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true
  }
}
503IDENTITY_PROVIDER_UNAVAILABLEKhông đọc được JWKS của bạn

AIHUB không tải được endpoint JWKS của Organization bạn. Đây là lỗi 503 chứ không phải 401 — API key của bạn vẫn ổn, nên đừng đổi key.

{
  "error": {
    "code": "IDENTITY_PROVIDER_UNAVAILABLE",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": true
  }
}
504AI_SERVICE_TIMEOUTQuá thời gian chấm

Chấm vượt ngân sách thời gian. Riêng Speaking, chỉ retry nếu một lần chấm thêm là chấp nhận được.

{
  "error": {
    "code": "AI_SERVICE_TIMEOUT",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
‹ Quay lại Chấm Speaking