WanduraDocsBeta
BetaDocs đang ở bản beta và còn thay đổi. Thấy chỗ sai, khó hiểu hoặc còn thiếu? Hãy cho chúng tôi biết.
Lịch sử thay đổi

Lịch sử: Tạo ảnh và video: Jobs API

Mọi lần sửa trang này, mới nhất ở trên. Mở từng mục để xem đã đổi gì.

← Tạo ảnh và video: Jobs API

  1. 17/10/2026 · +3 −3 dòng
    Xem thay đổi
    ⋯
      
      - `url` là link HTTPS trên storage của Wandura (Wandura CDN), tải thẳng bằng GET thường. Đó không phải link của bên thứ ba nào.
    - - **Lưu 72 giờ.** `expires_at` cho biết chính xác khi nào hết hạn. Hãy chép file về storage của bạn trước đó.
    + - **Mở được ít nhất 7 ngày.** `expires_at` cho biết link được bảo đảm tới khi nào. Cần giữ lâu hơn thì hãy chép file về storage của bạn trước đó.
      - Metadata đọc từ chính file: `type`, `width`, `height`, `duration` và `fps` (video), `size_bytes`, `seed`. Giá trị không đọc được là `null`.
      - File mẫu của key test có metadata `null` và không hết hạn.
    - - Bản ghi job được giữ lâu hơn 72 giờ nhiều: `GET /v2/jobs/{job_id}` vẫn trả lời cho job cũ.
    + - Bản ghi job được giữ lâu hơn 7 ngày nhiều: `GET /v2/jobs/{job_id}` vẫn trả lời cho job cũ.
      
      ## Webhook {#webhooks}
    ⋯
      | Thời gian job tối đa | ảnh 60 s, video 300 s | Theo style (`max_job_seconds`). Quá mức này job kết thúc `timeout`, không tính tiền. |
      | Thời gian trả lời submit | dưới 3 giây | Submit chỉ kiểm tra, giữ chỗ giá và xếp job vào hàng. |
    - | File output | 72 giờ | Xem [Output](#output). |
    + | File output | ít nhất 7 ngày | Xem [Output](#output). |
      
      Trạng thái và thông báo bảo trì: [wandura.instatus.com](https://wandura.instatus.com). Chưa cam kết SLA uptime.
    ⋯
  2. 16/10/2026 · +39 −1 dòng
    Xem thay đổi
      # Tạo ảnh và video: Jobs API
      
    - > **TL;DR** — `POST /v2/jobs` với một model, một style và dữ liệu đầu vào của bạn sẽ trả về `job_id` sau khoảng một giây. Wandura tạo kết quả ở nền rồi POST job cuối cùng (có ký) tới `webhook_url` của bạn; `GET /v2/jobs/{job_id}` là đường dự phòng. Key test (`wdr_test_…`) là sandbox miễn phí. Body sai bị từ chối ngay bằng `422` kèm lý do; job `failed`, `timeout`, bị huỷ hoặc bị moderation chặn thì **không bị tính tiền**.
    + > **TL;DR** — `POST /v2/jobs` với một model, một style và dữ liệu đầu vào của bạn sẽ trả về `job_id` sau khoảng một giây. Wandura tạo kết quả ở nền rồi POST job cuối cùng (có ký) tới `webhook_url` của bạn; `GET /v2/jobs/{job_id}` là đường dự phòng. Key test (`wdr_test_…`) là sandbox miễn phí. Body sai bị từ chối ngay bằng `422` kèm lý do; job `failed`, `timeout`, bị huỷ hoặc bị moderation chặn thì **không bị tính tiền**. Đây là cửa khuyên dùng cho mọi tích hợp mới.
      
      ## Cơ bản {#basics}
    ⋯
      | `webhook_url` | Tuỳ chọn. URL https công khai nhận job cuối cùng, ký bằng Jobs API signing secret của product, hoặc nếu product chưa có thì bằng signing secret của Webhook endpoint. Cần có một trong hai trước (xem [Webhook](#webhooks)). |
      | `end_user_id` | Tuỳ chọn. Id của người dùng trong hệ thống của bạn; khi gửi, giới hạn theo ngày cho từng người sẽ áp dụng (xem [Giới hạn](#limits)). |
    + | `lane` | **Đang triển khai.** Tuỳ chọn: `priority` (mặc định) hoặc `relax`. Xem [Lane Relax và đầu vào riêng của style](#lane-and-inputs). |
    + | `inputs` | **Đang triển khai.** Object tuỳ chọn: các đầu vào riêng của style mà không trường nào ở trên mang được. Xem [Lane Relax và đầu vào riêng của style](#lane-and-inputs). |
      
      - **URL đầu vào được tải khi job bắt đầu chạy**, không phải lúc submit. URL không tải được sẽ làm job `failed`, không tính tiền. Giữ URL presigned còn hạn ít nhất bằng `max_job_seconds` của style cộng 10 phút.
      - **Huỷ** được khi job còn `queued`: `200`, status `cancelled`, không tính tiền, và webhook vẫn được gửi. Khi job đã `processing` nó chạy tới cùng, và huỷ trả `409 JOB_NOT_CANCELLABLE`.
      
    + ## Lane Relax và đầu vào riêng của style {#lane-and-inputs}
    + 
    + **Đang triển khai.** Hai trường tuỳ chọn của `POST /v2/jobs`, để style nào key chạy được cũng chạy được thành job. Body không có hai trường này được trả lời y như trước.
    + 
    + **`lane`**: `priority` (mặc định) hoặc `relax`.
    + 
    + | | `priority` | `relax` |
    + |---|---|---|
    + | Giá | Giá Priority của style | Giá Relax của style, không bao giờ cao hơn Priority |
    + | Hạn chót | `max_job_seconds`; quá hạn thì job kết thúc `timeout`, không tính tiền | Không có: job xếp hàng tới lượt thì chạy |
    + | Khi product đã đầy | `429 PRODUCT_BUSY` | Không bao giờ bị từ chối vì lý do đó; job chờ ở `queued` |
    + 
    + Body của job giống nhau ở cả hai lane (không có trường `lane`). Cả hai giá có trong catalog công khai (`GET /v2/public/styles`, `price.priority` và `price.relax`).
    + 
    + **`inputs`**: object chứa các đầu vào riêng của style mà không trường nào trong bảng trên mang được, đặt tên đúng như trong schema đầu vào của style. Ví dụ: công tắc `keep_audio`, trường chữ thứ hai (`prompt` điền trường đầu tiên), `mask_url`, hoặc `video_url` trên style ra ảnh.
    + 
    + ```bash
    + curl -X POST https://api.wandura.ai/v2/jobs \
    +   -H "Authorization: Bearer $WANDURA_KEY" -H "Content-Type: application/json" \
    +   -d '{"model": "wandura-video-v1", "style": "<style id>", "image_urls": ["https://…/photo.jpg"], "lane": "relax", "inputs": {"keep_audio": false}}'
    + ```
    + 
    + - **Tìm đầu vào của một style ở đâu**: `GET /v2/public/styles/{style}` → `inputs` (không cần key). OpenAPI của từng style, `GET /v2/public/styles/{style}/openapi.json`, có sẵn body `POST /v2/jobs` đúng cho style đó, kèm ví dụ.
    + - Đầu vào nào đã có trường ở trên mang thì gửi bằng trường đó, không gửi trong `inputs`: `{"field": "inputs.image_urls", "reason": "send it as image_urls"}`.
    + - Style có đầu vào **bắt buộc** không thuộc các trường ở trên chỉ chạy khi body gửi `inputs`. Style đó không có trong `GET /v2/styles` hay schema của model; không gửi `inputs` thì nhận đúng `422` như một style không tồn tại.
    + - `GET /v2/models/{model_id}/schema` chỉ liệt kê các trường trong bảng trên; `lane` và `inputs` nằm trong [OpenAPI](https://api.wandura.ai/v2/openapi.json) (`JobRequest`).
    + - Style ra âm thanh chưa có trên Jobs API.
    + 
    + Lỗi ở hai trường này trả về trong `details` của `422 INVALID_INPUT`, như mọi trường khác:
    + 
    + | `field` | `reason` |
    + |---|---|
    + | `lane` | `must be priority or relax` |
    + | `inputs` | `must be an object of the style's own inputs` |
    + | `inputs.<name>` | `send it as <field>` · `style <id> does not take this input` · `must be true or false` · `must be a public https URL (at most 8192 characters)` · `must be a list of 1 to 10 https URLs` · `must be a string of at most 4000 characters` · `required by style <id>` |
    + 
      ## Validation chặt và đồng bộ {#validation}
      
    ⋯
  3. 16/10/2026 · +3 −3 dòng
    Xem thay đổi
    ⋯
      | `negative_prompt`, `aspect_ratio`, `resolution`, `duration`, `seed` | Chỉ cho style có liệt kê trong `inputs`. Xem [Validation](#validation). |
      | `num_outputs` | Tuỳ chọn, phải là `1`: mỗi job một output. |
    - | `webhook_url` | Tuỳ chọn. URL https công khai nhận job cuối cùng, có ký. Cần có Jobs API signing secret của product trước (xem [Webhook](#webhooks)). |
    + | `webhook_url` | Tuỳ chọn. URL https công khai nhận job cuối cùng, ký bằng Jobs API signing secret của product, hoặc nếu product chưa có thì bằng signing secret của Webhook endpoint. Cần có một trong hai trước (xem [Webhook](#webhooks)). |
      | `end_user_id` | Tuỳ chọn. Id của người dùng trong hệ thống của bạn; khi gửi, giới hạn theo ngày cho từng người sẽ áp dụng (xem [Giới hạn](#limits)). |
      
    ⋯
      Mỗi job có `webhook_url` nhận **một** POST khi đạt status cuối cùng (không có webhook trung gian). Body đúng bằng thứ `GET /v2/jobs/{job_id}` trả về tại thời điểm đó.
      
    - 1. **Tạo Jobs API signing secret của product một lần**: ở [console](https://open.wandura.ai/webhooks), mục "Jobs API signing secret" → Create. Secret chỉ hiện một lần; Roll thay ngay lập tức. Khi chưa có secret, submit kèm `webhook_url` bị từ chối bằng `422`.
    + 1. **Có một signing secret, làm một lần**: ở [console](https://open.wandura.ai/webhooks), hoặc lưu một URL Webhook endpoint (signing secret của nó ký luôn webhook của job), hoặc tạo riêng "Jobs API signing secret" (Create; chỉ hiện một lần; Roll thay ngay lập tức). Product có Jobs API signing secret thì secret đó ký webhook của job. Khi chưa có cái nào trong hai, submit kèm `webhook_url` bị từ chối bằng `422`.
      2. **Verify mọi request** trên **raw body**: `X-Signature` là HMAC-SHA256 dạng hex của `X-Timestamp + "." + raw body` bằng secret của bạn, và `X-Timestamp` (unix giây) lệch hiện tại không quá 5 phút.
      3. **Trả `2xx` trong 10 giây**, rồi mới xử lý việc của bạn. Dedupe theo `job_id` (hoặc header `Wandura-Event-Id`, giống nhau ở mọi lần retry): giao tin ít nhất một lần.
    ⋯
      ## Lỗi {#errors}
      
    - Mọi câu trả lời lỗi có dạng `{"error": {"code", "message", "retryable"}}`, thêm `details` cho `INVALID_INPUT`. Rẽ nhánh theo `code`; khi nhờ hỗ trợ, đưa kèm header `X-Request-Id`.
    + Mọi câu trả lời lỗi có dạng `{"error": {"code", "message", "retryable"}}`, thêm `details` cho `INVALID_INPUT`. Rẽ nhánh theo `code`; khi nhờ hỗ trợ, đưa kèm header `X-Request-Id`. **Đang triển khai:** mỗi lỗi có thêm `docs_url`, link tới mục của nó trên trang [Lỗi](errors.md#jobs-errors), và các header `Wandura-Error-Code`, `Wandura-Should-Retry` (xem [Thân lỗi và header](errors.md#error-body)).
      
      | HTTP | `code` | `retryable` | Ý nghĩa |
    ⋯
  4. 16/10/2026 · +1 −1 dòng
    Xem thay đổi
    ⋯
      | 401 | `UNAUTHORIZED` | false | Thiếu key, key lạ, đã thu hồi hoặc hết hạn. |
      | 402 | `INSUFFICIENT_CREDITS` | false | Ví của product không đủ trả cho job. Nạp thêm rồi thử lại. |
    - | 403 | `FORBIDDEN` | false | Key hợp lệ nhưng không được làm việc này. Dự phòng: hiện chưa trả. |
    + | 403 | `FORBIDDEN` | false | Key hợp lệ nhưng không được làm việc này. Đang triển khai: key quyền Read only gửi hoặc huỷ job, hoặc key chỉ được chạy style khác (xem [Khoá API](concepts.md#api-keys)). Trước đó: chưa trả. |
      | 404 | `NOT_FOUND` | false | Không có job, model hoặc endpoint đó cho key này. |
      | 409 | `IDEMPOTENCY_KEY_REUSED` | false | `Idempotency-Key` này đã dùng với body khác. |
    ⋯
  5. 15/10/2026 · +7 −3 dòng
    Xem thay đổi
    ⋯
      # X-RateLimit-Remaining: 59
      # X-RateLimit-Reset: 1791897360
    + # X-Concurrency-Limit: 20
    + # X-Concurrency-Running: 3
    + # X-Concurrency-Waiting: 0
      # {"job_id":"run_QVqsXwr7VGSP","status":"queued","model":"wandura-video-v1","created_at":"2026-10-13T13:15:40.825Z"}
      
    ⋯
      | 409 | `JOB_NOT_CANCELLABLE` | false | Chỉ huỷ được job đang queued. |
      | 429 | `RATE_LIMITED` | true | Product gửi quá nhiều job trong phút này. Thử lại sau `Retry-After`. |
    + | 429 | `PRODUCT_BUSY` | true | Product đã hết suất chạy và hàng chờ đầy. Thử lại sau `Retry-After` (khoảng 5 s). |
      | 429 | `END_USER_LIMIT_REACHED` | true | End user này đã chạm giới hạn job trong ngày. Thử lại sau `Retry-After` (reset 00:00 UTC). |
      | 500 | `INTERNAL_ERROR` | true | Phía Wandura có sự cố. Thử lại với cùng `Idempotency-Key`. |
    - | 503 | `SERVICE_UNAVAILABLE` | true | Style này tạm thời không chạy được trên key live. Key test vẫn trả file mẫu. |
    + | 503 | `SERVICE_UNAVAILABLE` | true | Style này tạm thời không chạy được trên key live (key test vẫn trả file mẫu). Hoặc hàng đợi job tạm thời không nhận: không có gì được tạo hay tính tiền; thử lại sau `Retry-After` với cùng `Idempotency-Key`. |
      
    - `429` luôn kèm header `Retry-After` (giây). Chờ đúng khoảng đó, cộng thêm một chút jitter ngẫu nhiên, rồi retry với **cùng** `Idempotency-Key`. Chỉ retry những lỗi có `retryable`.
    + `429` luôn kèm header `Retry-After` (giây). Chờ đúng khoảng đó, cộng thêm một chút jitter ngẫu nhiên, rồi retry với **cùng** `Idempotency-Key`. Chỉ retry những lỗi có `retryable`. Câu trả lời submit, kể cả `429`, cũng có `X-Concurrency-Limit`, `X-Concurrency-Running` và `X-Concurrency-Waiting`: xem [Hàng chờ và nghẽn](queue-and-congestion.md).
      
      ```http
    ⋯
      |---|---|---|
      | Tốc độ submit | 60 job mỗi phút mỗi product | Key live và key test tính riêng. Vượt mức: `429 RATE_LIMITED` kèm `Retry-After`. Mỗi submit trả `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`. |
    - | Job chạy cùng lúc | 20 mỗi product | Job thừa chờ ở `queued`. Job còn chờ tới hết thời gian tối đa của nó sẽ kết thúc `timeout`, không tính tiền. |
    + | Job chạy cùng lúc | 20 mỗi product | Job thừa chờ ở `queued`. Hàng chờ chứa số job bằng số suất chạy; quá mức đó, `429 PRODUCT_BUSY` kèm `Retry-After`. Job còn chờ tới hết thời gian tối đa của nó sẽ kết thúc `timeout`, không tính tiền. Câu trả lời submit cho thấy các số này (`X-Concurrency-*`). |
      | Mỗi end user | 20 job mỗi ngày | Chỉ khi bạn gửi `end_user_id`. Reset 00:00 UTC; `429 END_USER_LIMIT_REACHED`. |
      | Thời gian job tối đa | ảnh 60 s, video 300 s | Theo style (`max_job_seconds`). Quá mức này job kết thúc `timeout`, không tính tiền. |
    ⋯
  6. 13/10/2026 · Tạo trang
↑↓ chọnEnter mởEsc đóng

Gửi góp ý

Góp ý được gửi thẳng tới đội Wandura, kèm địa chỉ trang này.

0 / 4000