POSThttps://api.aihubproduction.com/v1/ielts/writing/task1/grade

Chấm bài Task 1

Chấm bài mô tả biểu đồ. Cần ảnh biểu đồ tải được, loại biểu đồ, đề bài và bài làm.

Request

FieldTypeBắt buộcMô tả
questionstringBẮT BUỘCĐề bài mô tả biểu đồ, 1–2.000 ký tự.
chart_typestringBẮT BUỘCLoại biểu đồ, phân biệt HOA THƯỜNG, đúng một trong: Bar Chart | Line Graph | Pie Chart | Table | Map | Process Diagram | Multiple Graphs.
essaystringBẮT BUỘCBài làm Task 1, 1–20.000 ký tự.
image_urlstring (uri)BẮT BUỘCẢnh biểu đồ dạng HTTP(S), tối đa 2.000 ký tự. Phải trỏ tới ảnh thật mà AIHUB có thể truy cập.
languagestringtuỳ chọnNgôn ngữ nhận xét. Hiện chỉ nhận vi; nhận xét luôn trả về bằng tiếng Việt.

Response

Envelope { data, meta } của AIHUB. data khớp hợp đồng chấm bài: overall_band chạy từ 0 đến 9 theo bội số 0.5, criteria luôn có đúng 4 phần tử theo thứ tự cố định (bắt đầu bằng task_achievement), kèm summary, suggestions, next_steps và annotations trích nguyên văn câu trong bài. meta cho request_id để báo hỗ trợ, service, operation và các số đo thời gian; correlation_id chỉ xuất hiện khi bạn gửi X-Correlation-Id.

Lưu ý

  • image_url trong ví dụ trỏ tới biểu đồ mẫu AIHUB công bố, nên lệnh chạy được ngay. Khi chấm bài thật, thay bằng ảnh biểu đồ của bạn và đảm bảo AIHUB có thể truy cập ảnh. Nếu không tải được ảnh, yêu cầu vẫn có thể trả kết quả không chính xác.
  • chart_type phân biệt HOA THƯỜNG và chỉ nhận 7 giá trị đã liệt kê; gửi "bar chart" hoặc một chủ đề như "environment" đều bị 400 INVALID_REQUEST.
  • Đổi bất kỳ trường nào trong body thì phải dùng một Idempotency-Key mới, nếu không sẽ nhận 409 IDEMPOTENCY_CONFLICT.
  • Body vượt 256 KB trả về 413 PAYLOAD_TOO_LARGE. Trường lạ trong body 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. Bản ghi Idempotency-Key giữ 24 giờ.
# Ba biến dưới là ví dụ — thay bằng giá trị thật của bạn, và chỉ chạy trên server của bạn.
AIHUB_API_KEY="aihub_sk_..."            # API key của Organization, có scope writing.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

# Gán UUID MỘT LẦN cho mỗi lần chấm, rồi dùng lại nguyên biến này khi retry.
# Chạy lại dòng này = một lần chấm mới, bị tính phí thêm.
AIHUB_IDEMPOTENCY_KEY="$(uuidgen)"

curl -X POST 'https://api.aihubproduction.com/v1/ielts/writing/task1/grade' \
  -H "X-API-Key: $AIHUB_API_KEY" \
  -H "X-User-Identity: $AIHUB_USER_IDENTITY" \
  -H "Idempotency-Key: $AIHUB_IDEMPOTENCY_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "question": "The chart below shows the total number of minutes (in billions) of telephone calls in the UK, divided into three categories, from 1995-2002. Summarise the information by selecting and reporting the main features, and make comparisons where relevant.",
  "chart_type": "Bar Chart",
  "image_url": "https://s3.wispace.app/ielts-task1/ca95bd4ab522946d",
  "essay": "The bar chart illustrates the total duration, measured in billions of minutes, of telephone calls made in the United Kingdom across three categories between 1995 and 2002.\n\nOverall, local fixed line calls were the most popular type throughout the entire period, although their share declined after 1999. In contrast, mobile calls grew steadily and consistently over the eight years.\n\nIn 1995, local fixed line calls accounted for approximately 72 billion minutes, which was considerably higher than national and international fixed line calls at around 38 billion minutes. Mobile calls were negligible at that point, standing at roughly 2 billion minutes.\n\nLocal fixed line usage rose to a peak of about 90 billion minutes in 1999, before falling back to approximately 72 billion minutes by 2002. Meanwhile, national and international calls increased gradually and reached around 61 billion minutes in the final year.\n\nMobile calls, despite starting from the lowest position, experienced the most dramatic growth, rising to about 46 billion minutes by 2002, a more than twentyfold increase."
}'

Lỗi thường gặp

19 mã dưới đây áp dụng cho cả hai endpoint chấm. Mọi lỗi trả về cùng một envelope { error: { code, message, request_id, retryable, retry_after_ms? } }. Giá trị retry_after_ms trong ví dụ chỉ minh họa; hãy dùng giá trị response thực tế. Rẽ nhánh theo code chứ không theo message, vì message có thể đổi câu chữ. Chỉ tự động retry khi retryable là true và luôn giữ cùng Idempotency-Key; riêng 409 do request giống hệt đang chạy thì chờ request đầu hoàn tất rồi gửi lại cùng key và body.

400INVALID_REQUESTRequest không hợp lệ

Body sai kiểu dữ liệu, thiếu trường bắt buộc, quá độ dài, có trường lạ, hoặc Idempotency-Key thiếu/rỗng/quá 255 byte. Sửa request rồi gọi lại; retry y hệt là vô nghĩa.

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

Thiếu, không nhận ra, đã thu hồi hoặc hết hạn API key. Key hiển thị một lần lúc tạo nên cần xoay vòng nếu đã mất.

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

Gọi endpoint user-scoped mà không có X-User-Identity. Cả hai endpoint chấm đều cần header này.

{
  "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 1–256 ký tự ASCII không khoảng trắng, hoặc Signed User Assertion không vượt kiểm chữ ký. Không có fallback: cấu hình Identity active buộc phải dùng Signed User Assertion.

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

API key không có scope writing.grade. Liên hệ AIHUB để mở rộng scope của key.

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

Key chỉ chạy ở Environment khác với hostname đang gọi. Dùng đúng key của host đó; client không chọn Environment bằng header.

{
  "error": {
    "code": "ENVIRONMENT_NOT_ALLOWED",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
404NOT_FOUNDSai route

Không có route này. Các operation chấm nằm dưới /v1/ielts/..., ví dụ /v1/writing/task2/grade là 404.

{
  "error": {
    "code": "NOT_FOUND",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
409IDEMPOTENCY_CONFLICTXung đột Idempotency-Key

Dùng lại một key với body khác, hoặc một request giống hệt đang chạy. retryable là false nên không gửi lại ngay; body khác thì lấy key mới, còn request đang chạy thì chờ nó xong rồi gửi lại cùng key và cùng body.

{
  "error": {
    "code": "IDEMPOTENCY_CONFLICT",
    "message": "…",
    "request_id": "req_01M23NT8MJW22AYX6FVT17F5XF",
    "retryable": false
  }
}
413PAYLOAD_TOO_LARGEBody vượt 256 KB

Body lớn hơn giới hạn của endpoint. Rút ngắn bài làm.

{
  "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 song song

Quá nhiều request đang chạy cùng lúc. Giảm số request chạy song song thay vì chờ lâu hơn.

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

Đã dùng hết hạn mức request trong tháng. retryable là true và retry_after_ms cho biết thời gian còn lại đến đầu tháng UTC tới; chờ kỳ reset hoặc nâng hạn mức.

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

Lỗi không lường trước ở phía chúng tôi. Mã này luôn có retryable là false — báo lại kèm request_id thay vì retry.

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

Yêu cầu không hoàn tất. retryable là false với lỗi 4xx (như ví dụ), true với lỗi 5xx; chỉ thử lại khi response thực tế cho phép.

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

Kết quả trả về có cấu trúc không hợp lệ. Không retry; báo lại kèm request_id.

{
  "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; mã này không có retry_after_ms nên chọn thời gian lùi phù hợp.

{
  "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_UNAVAILABLENguồn xác minh User Identity không khả dụng

AIHUB không đọc được Identity configuration của Organization, hoặc không lấy được JWKS khi xác minh Signed User Assertion. Lỗi đọc cấu hình có thể xảy ra cả khi bạn dùng Declared User ID; không tự chuyển sang chế độ khác. API key vẫn hợp lệ.

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

Chấm vượt ngân sách 60 giây. Retry bằng chính Idempotency-Key cũ: nếu lần chấm nền đã xong, kết quả được trả lại mà không tính phí thêm.

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