Running a model
Submit a request
/<address>on https://queue.auray.runRun auray-ai/hunyuan-3d/image-to-3d
#Authentication
Authorization: Bearer auray_sk_… — a key with the scope the route names.
#Request
#Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
wait | integer | no | Hold the request open until the job settles, up to 300 seconds. The answer is still a status document; timed_out says the wait ran out rather than the job failing. One product refuses it outright and says so with wait_unsupported. 1 to 300. |
logs | string | no | Include the runner's log lines on a read. Off by default, because a status polled at 10 Hz that carries a growing log is the same lines paid for a hundred times. One of "1", "0", "true", "false". |
webhook | string | no | An https address to POST this job's outcome to once, beside any endpoint the account has registered. Checked when it is stored and again before it is sent: https only, no user-info, no private or loopback host, at most 2,000 characters. Signed Auray-Signature v2 with a kid; verify it against our JWKS. No ownership challenge here, so the body names the account the job belongs to in account (the id GET /v1/me returns), inside what the signature covers: a receiver compares it with its own and refuses anything else. A URL. |
fal_webhook | string | no | An https address to POST this job's outcome to once, beside any endpoint the account has registered. Checked when it is stored and again before it is sent: https only, no user-info, no private or loopback host, at most 2,000 characters. Signed Auray-Signature v2 with a kid; verify it against our JWKS. No ownership challenge here, so the body names the account the job belongs to in account (the id GET /v1/me returns), inside what the signature covers: a receiver compares it with its own and refuses anything else. An alias for webhook; sending both with different values is refused with conflicting_options. A URL. |
max_queue_length | integer | no | Refuse with 429 queue_too_long rather than queue behind more than this many waiting requests. 0 is a real value and means "only if nobody is waiting". Decided before anything is charged. On a model that does not queue — every catalogue model today, whose lifecycle.queue in GET /v1/models is refuses — sending it is refused 422 queue_not_offered before anything is charged. 0 to 2147483647. |
fal_max_queue_length | integer | no | Refuse with 429 queue_too_long rather than queue behind more than this many waiting requests. 0 is a real value and means "only if nobody is waiting". Decided before anything is charged. On a model that does not queue — every catalogue model today, whose lifecycle.queue in GET /v1/models is refuses — sending it is refused 422 queue_not_offered before anything is charged. An alias for max_queue_length; sending both with different values is refused with conflicting_options. 0 to 2147483647. |
#Headers
| Name | Type | Required | Description |
|---|---|---|---|
X-Auray-Priority | string | no | low puts this request behind every normal one. Nothing else changes. On a model that does not queue — every catalogue model today, whose lifecycle.queue in GET /v1/models is refuses — sending it is refused 422 queue_not_offered before anything is charged. One of "normal", "low". |
X-Fal-Queue-Priority | string | no | low puts this request behind every normal one. Nothing else changes. On a model that does not queue — every catalogue model today, whose lifecycle.queue in GET /v1/models is refuses — sending it is refused 422 queue_not_offered before anything is charged. An alias for X-Auray-Priority; sending both with different values is refused with conflicting_options. One of "normal", "low". |
X-Auray-Request-Timeout | number | no | Seconds to wait for a seat. A request still waiting past it is failed request_timeout and refunded. It is a time-to-START and never a bound on inference: a job that has been dispatched is not stopped by it. On a model that does not queue — every catalogue model today, whose lifecycle.queue in GET /v1/models is refuses — it is accepted and has nothing to bound: such a model starts at once or refuses at once. 1 to 86400. |
X-Fal-Request-Timeout | number | no | Seconds to wait for a seat. A request still waiting past it is failed request_timeout and refunded. It is a time-to-START and never a bound on inference: a job that has been dispatched is not stopped by it. On a model that does not queue — every catalogue model today, whose lifecycle.queue in GET /v1/models is refuses — it is accepted and has nothing to bound: such a model starts at once or refuses at once. An alias for X-Auray-Request-Timeout; sending both with different values is refused with conflicting_options. 1 to 86400. |
X-Auray-Covered-Only | string | no | Run this job only if a pass or a promotion of yours pays for it. A job neither pays for is refused 409 not_covered before anything is held or charged — or, when your pass had ended by the time the job started, refunded and refused so — where without this header your credits would pay for it; a job your plan runs only through a pass is refused as the plan refuses it (model_not_in_plan, pass_does_not_cover). For a job it lets through, the submit's answer on queue.auray.run says credits_charged: 0 and what paid in coverage, and so does GET /v1/jobs/{id}; a run on auray.run answers the job's output, which says neither — read GET /v1/jobs/{id} with its request_id. true is read as 1; any other value as no header. One of "1", "true". |
#Body
application/json, required.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
image_path | string | yes | — | The photograph to build from: the path that POST /v1/uploads with address: "auray-ai/hunyuan-3d/image-to-3d" answered, sent once its bytes have been PUT. A path from POST /v1/uploads; this platform never fetches a URL you give it. |
tier | string | yes | — | Required, with no default — and the refusal body carries no list of valid values, unlike video. One of "geometry", "textured", "rigged", "controlled-object", "controlled-character". |
out_format | string | no | "glb" | fbx only means anything on a tier that produces a skeleton. One of "glb", "fbx". |
control_type | string | no | — | Coupled to the tier rather than free — controlled-object takes bbox, controlled-character takes pose. One of "bbox", "pose". |
control_data | number[] or number[][] | no | — | A JSON list whose shape follows control_type, never a string. For bbox (controlled-object): three numbers [width, height, depth] — x across, y up, z front to back — each above 0 and at most 1; they are an aspect ratio, scaled so the longest is 1.0 before the model reads them. For pose (controlled-character): one row of six numbers per bone, [x1, y1, z1, x2, y2, z2] from the bone's start to its end, in the same axes, the figure standing about 1.8 units tall with its feet near y = -1, at most 512 rows. The model reads these coordinates as they are and was trained on Tencent's 51-bone A-pose — this field's second worked value, in openapi.json's examples and on the reference page, and what the desktop sends — so start from it and move the bones: a skeleton far from it does not fail, it steers the mesh somewhere the model never learned. |
num_inference_steps | integer | no | 50 | More steps, more detail, a longer run. Outside 1–100 is ignored rather than refused. Documented range: 1 to 100. |
seed | integer | no | — | Reuse one to get the same mesh back. Outside the range it is refused with 422 seed_out_of_range, before any charge. Documented range: 0 to 2,147,483,647. |
source_name | string | no | — | A label carried through to the stored job, for your own bookkeeping. |
idempotency_key | string | no | — | Your own name for this request. Send the same one twice and the second call is answered with the first request rather than charged again. Idempotency-Key: as a header is accepted as an alias — that is the spelling a retrying proxy replays, and the one to use when running a model on auray.run, where a request that outlives its connection is answered 504 and recovered by replay. Omit it and the platform mints one. 1 to 64 characters. |
#Example request
curl -X POST https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d \
-H "Authorization: Bearer $AURAY_API_KEY" \
-H "content-type: application/json" \
-d '{
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
}'import { createClient } from "@auray/client";
const auray = createClient(); // reads AURAY_API_KEY
const job = await auray.queue.submit("auray-ai/hunyuan-3d/image-to-3d", {
input: {
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
},
});
console.log(job.request_id, job.status);from auray_client import Client
auray = Client() # reads AURAY_API_KEY
job = auray.queue.submit(
"auray-ai/hunyuan-3d/image-to-3d",
input={
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
},
)
print(job["request_id"], job["status"]){
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "submit_job",
"arguments": {
"address": "auray-ai/hunyuan-3d/image-to-3d",
"input": {
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
}
}
}
}const res = await fetch("https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.AURAY_API_KEY}`,
"content-type": "application/json",
},
body: JSON.stringify({
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
}),
});
console.log(await res.json());import os, requests
r = requests.post(
"https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d",
headers={"Authorization": f"Bearer {os.environ['AURAY_API_KEY']}"},
json={
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
},
)
r.raise_for_status()
print(r.json())package main
import (
"bytes"
"fmt"
"io"
"net/http"
"os"
)
func main() {
body := []byte(`{
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
}`)
req, err := http.NewRequest("POST", "https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d", bytes.NewReader(body))
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+os.Getenv("AURAY_API_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, _ := io.ReadAll(res.Body)
fmt.Println(res.Status, string(out))
}<?php
$ch = curl_init("https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("AURAY_API_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"image_path" => "your-user-id/your-idempotency-key.png",
"tier" => "geometry",
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $response, PHP_EOL;require "net/http"
require "json"
uri = URI("https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch("AURAY_API_KEY")}"
req["Content-Type"] = "application/json"
req.body = {
"image_path" => "your-user-id/your-idempotency-key.png",
"tier" => "geometry"
}.to_json
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code, res.bodyimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
String body = """
{
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d"))
.header("Authorization", "Bearer " + System.getenv("AURAY_API_KEY"))
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body());
}
}using System.Net.Http.Headers;
using System.Text;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("AURAY_API_KEY"));
using var request = new HttpRequestMessage(HttpMethod.Post, "https://queue.auray.run/auray-ai/hunyuan-3d/image-to-3d");
var body = """
{
"image_path": "your-user-id/your-idempotency-key.png",
"tier": "geometry"
}
""";
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine($"{(int)response.StatusCode} {await response.Content.ReadAsStringAsync()}");#Responses
#200 OK
Accepted, and charged and running — or, when the platform is full, waiting in the queue and charged when it starts: credits_charged is what has been taken, credits_quoted what it costs. Always this status: a submit's outcome is in status, never in the status line.
#202 Accepted
The dispatch could not be confirmed (dispatch_unresolved): the charge stands, the request exists and is IN_QUEUE, and the body is its status document with message and docs beside it. Poll status_url — never resend under a new key, which would be a second charge. If it never starts, it is declared lost and refunded.
#400 Bad Request
A refusal: error_type is ConflictError or ValidationError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#401 Unauthorized
A refusal: error_type is AuthenticationError. On auray.run, a request that ran and failed: error_type is AuthenticationError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#402 Payment Required
A refusal: error_type is PaymentError. On auray.run, a request that ran and failed: error_type is PaymentError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#403 Forbidden
A refusal: error_type is PermissionError. On auray.run, a request that ran and failed: error_type is PermissionError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#404 Not Found
A refusal: error_type is NotFoundError. On auray.run, a request that ran and failed: error_type is NotFoundError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#405 Method Not Allowed
A refusal: error_type is ValidationError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#409 Conflict
A refusal: error_type is CancellationError or ConflictError. On auray.run, a request that ran and failed: error_type is CancellationError or ConflictError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#410 Gone
A refusal: error_type is GoneError or NotFoundError. On auray.run, a request that ran and failed: error_type is GoneError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#413 Payload Too Large
A refusal: error_type is PayloadTooLargeError. On auray.run, a request that ran and failed: error_type is PayloadTooLargeError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#422 Unprocessable Content
A refusal of what the request says — an option, the body, a field — decided before anything is charged, or the model's own refusal of the request as it was written (its content filter, a value or a file it would not take), refunded: error_type is ContentPolicyError or ValidationError, and detail is a list of {loc, msg, type}, loc naming where (["body"] when the parser names no field). On auray.run, a request that ran and failed: error_type is ContentPolicyError or ValidationError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#428 Precondition Required
A refusal: error_type is PreconditionError. On auray.run, a request that ran and failed: error_type is PreconditionError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#429 Too Many Requests
A refusal: error_type is CapacityError or RateLimitError. On auray.run, a request that ran and failed: error_type is RateLimitError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#451 Unavailable For Legal Reasons
A refusal: error_type is RegionError. On auray.run, a request that ran and failed: error_type is RegionError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#500 Internal Server Error
A refusal: error_type is ConfigurationError or InternalError. On auray.run, a request that ran and failed: error_type is ExecutionError or InternalError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#501 Not Implemented
A refusal: error_type is NotImplementedError. On auray.run, a request that ran and failed: error_type is NotImplementedError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#502 Bad Gateway
A refusal: error_type is ContentPolicyError or UpstreamError. On auray.run, a request that ran and failed: error_type is UpstreamError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#503 Service Unavailable
A refusal: error_type is CapacityError or ConfigurationError or InternalError or UpstreamError. On auray.run, a request that ran and failed: error_type is CapacityError or ConfigurationError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#504 Gateway Timeout
A refusal: error_type is TimeoutError. On auray.run, a request that ran and failed: error_type is TimeoutError. The code is in error, and every code is explained at https://auray.ai/docs/api/errors.
The error body: error, message, docs (the entry that explains it) and request_id.
#Status codes
| Status | Meaning |
|---|---|
200 | Accepted, and charged and running — or, when the platform is full, waiting in the queue and charged when it starts: credits_charged is what has been taken, credits_quoted what it costs. |
202 | The dispatch could not be confirmed (dispatch_unresolved): the charge stands, the request exists and is IN_QUEUE, and the body is its status document with message and docs beside it. |
400 | A refusal: error_type is ConflictError or ValidationError. |
401 | A refusal: error_type is AuthenticationError. |
402 | A refusal: error_type is PaymentError. |
403 | A refusal: error_type is PermissionError. |
404 | A refusal: error_type is NotFoundError. |
405 | A refusal: error_type is ValidationError. |
409 | A refusal: error_type is CancellationError or ConflictError. |
410 | A refusal: error_type is GoneError or NotFoundError. |
413 | A refusal: error_type is PayloadTooLargeError. |
422 | A refusal of what the request says — an option, the body, a field — decided before anything is charged, or the model's own refusal of the request as it was written (its content filter, a value or a… |
428 | A refusal: error_type is PreconditionError. |
429 | A refusal: error_type is CapacityError or RateLimitError. |
451 | A refusal: error_type is RegionError. |
500 | A refusal: error_type is ConfigurationError or InternalError. |
501 | A refusal: error_type is NotImplementedError. |
502 | A refusal: error_type is ContentPolicyError or UpstreamError. |
503 | A refusal: error_type is CapacityError or ConfigurationError or InternalError or UpstreamError. |
504 | A refusal: error_type is TimeoutError. |
Every refusal names its code, and every code is explained at Errors.