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

Chấm câu trả lời

Nhận audio và trả về transcript, band ước tính cùng feedback theo rubric.

Request

FieldTypeGiá trị mẫuBắt buộcMô tả
audiofile./answer.wavBẮT BUỘCMột tệp wav, mp3, m4a, webm hoặc ogg; tối thiểu 100 byte, tối đa 25 MiB. Ví dụ trỏ tới tệp trên máy bạn; muốn chạy thử không cần tệp, dùng POST /v1/ielts/speaking/grading-json với Published sample answer của AIHUB.
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.
  • Lệnh dùng -F nên curl tự sinh Content-Type multipart kèm boundary; không cần và không nên đặt header này.
  • 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 26 MiB 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 60 giây của gateway là trần của phía server — đặt timeout phía client tối thiểu 90 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

AIHUB_AUDIO_FILE="./answer.wav"         # đường dẫn tới tệp trên máy bạn; chỉ sửa biến này

curl -X POST 'https://api.aihubproduction.com/v1/ielts/speaking/grading' \
  -H "X-API-Key: $AIHUB_API_KEY" \
  -H "X-User-Identity: $AIHUB_USER_IDENTITY" \
  -F "audio=@${AIHUB_AUDIO_FILE}" \
  -F "part=1" \
  -F "question_id=p1_do-you-enjoy-living-in-your-city-or-hometown" \
  -F "prompt_text=Do you enjoy living in your city or hometown?" \
  -F "test_type=Practice" \
  -F "test_code=ielts-practice-01" \
  -F "transcript=I live in a small town."

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