Programmatic tools
Public discovery runs on haneoka.org. Job endpoints run on your local service; see the local computation guide for startup and complete examples.
Discover
Section titled “Discover”Discover the API
Section titled “Discover the API”/api/v1 Machine-readable entry points, request contracts and tool modules.
Example request
curl -sS "https://haneoka.org/api/v1"const response = await fetch("https://haneoka.org/api/v1");if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();Example response
HTTP/2 200 OK{}Trimmed for length; the real response contains more entries.
Complete OpenAPI
Section titled “Complete OpenAPI”/api/v1/openapi.json Machine-readable entry points, request contracts and tool modules.
Example request
curl -sS "https://haneoka.org/api/v1/openapi.json"const response = await fetch("https://haneoka.org/api/v1/openapi.json");if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();Example response
HTTP/2 200 OK{}Trimmed for length; the real response contains more entries.
Device computation modules
Section titled “Device computation modules”/api/v1/tools Machine-readable entry points, request contracts and tool modules.
Example request
curl -sS "https://haneoka.org/api/v1/tools"const response = await fetch("https://haneoka.org/api/v1/tools");if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();Example response
HTTP/2 200 OK{}Trimmed for length; the real response contains more entries.
Local computation
Section titled “Local computation”Local service capabilities
Section titled “Local service capabilities”/v1 Lists operations, queue concurrency and result lifetime.
Example request
curl -sS "http://127.0.0.1:8765/v1" \ -H "Authorization: Bearer ${localToken}"const response = await fetch("http://127.0.0.1:8765/v1", { headers: { Authorization: `Bearer ${localToken}`, },});if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();Example response
HTTP/2 200 OK{ "operations": [ "search", "evaluate", "growth", "timeline", "chart-image" ], "concurrency": 1, "resultTtlSeconds": 600}Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |
Submit a local calculation
Section titled “Submit a local calculation”/v1/jobs Returns 202 and a Location to poll. Bodies: 2 MiB; queue: eight; execution: one job, five minutes. Inventories stay on this host.
Request body application/json
| Name | Type | Description |
|---|---|---|
operationrequired | string | search, evaluate, growth, timeline, chart-image or resource-image. |
requestoptional | object | Required for calculations; use the corresponding type in tools/schema.json. |
Example request
curl -sS -X POST "http://127.0.0.1:8765/v1/jobs" \ -H "Authorization: Bearer ${localToken}" \ -H "Content-Type: application/json" \ --data '{"operation":"chart-image","server":"intl","songId":"100001","difficulty":"expert","locale":"en","height":720}'const response = await fetch("http://127.0.0.1:8765/v1/jobs", { method: "POST", headers: { Authorization: `Bearer ${localToken}`, "Content-Type": "application/json", }, body: JSON.stringify({ "operation": "chart-image", "server": "intl", "songId": "100001", "difficulty": "expert", "locale": "en", "height": 720 }),});if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();Example response
HTTP/2 202 AcceptedLocation: /v1/jobs/00000000-0000-4000-8000-000000000001{ "id": "00000000-0000-4000-8000-000000000001", "operation": "chart-image", "state": "queued"}Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |
Read job progress and result
Section titled “Read job progress and result”/v1/jobs/{id} States: queued, running, completed, failed. Results expire ten minutes after completion. Read result, identity and optional image URL.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | uuid | Job ID returned by submission. |
Example request
curl -sS "http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001" \ -H "Authorization: Bearer ${localToken}"const response = await fetch("http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001", { headers: { Authorization: `Bearer ${localToken}`, },});if (!response.ok) throw new Error(`HTTP ${response.status}`);const data = await response.json();Example response
HTTP/2 200 OK{ "id": "00000000-0000-4000-8000-000000000001", "operation": "search", "state": "completed", "createdAt": 1793030400000, "expiresAt": 1793031000000, "result": { "overall": [], "results": [], "stopReason": "complete" }}Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |
Cancel and delete a job
Section titled “Cancel and delete a job”/v1/jobs/{id} Closes the calculation context and removes the saved result. Later reads return 404.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | uuid | Job ID returned by submission. |
Example request
curl -sS -X DELETE "http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001" \ -H "Authorization: Bearer ${localToken}"const response = await fetch("http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001", { method: "DELETE", headers: { Authorization: `Bearer ${localToken}`, },});if (!response.ok) throw new Error(`HTTP ${response.status}`);Example response
HTTP/2 204 No ContentNo response body.
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |
Download a completed image
Section titled “Download a completed image”/v1/jobs/{id}/image.png Requires a completed chart-image job and the same local Bearer token. Returns PNG; 409 while not ready.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | uuid | Job ID returned by submission. |
Example request
curl -sS -o output.bin "http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001/image.png" \ -H "Authorization: Bearer ${localToken}"const response = await fetch("http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001/image.png", { headers: { Authorization: `Bearer ${localToken}`, },});if (!response.ok) throw new Error(`HTTP ${response.status}`);const blob = await response.blob();Example response
HTTP/2 200 OKBinary body (not shown).
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |
Render a resource image locally
Section titled “Render a resource image locally”/v1/resource-image Uses the same image recipes as the resource APIs. JSON: 8 MiB, output: 16 MiB, deadline: 50 seconds, one job at a time. See the image export guide for kind, data and viewer state.
Request body application/json
| Name | Type | Description |
|---|---|---|
kindrequired | string | team, gacha, gacha-history, stamp, chart, live2d or spine. |
datarequired | object | Website export model; see /reference/images/. |
Example request
curl -sS -o output.bin -X POST "http://127.0.0.1:8765/v1/resource-image" \ -H "Authorization: Bearer ${localToken}" \ -H "Content-Type: application/octet-stream" \ --data-binary @resource-image.jsonconst response = await fetch("http://127.0.0.1:8765/v1/resource-image", { method: "POST", headers: { Authorization: `Bearer ${localToken}`, "Content-Type": "application/octet-stream", }, body: file,});if (!response.ok) throw new Error(`HTTP ${response.status}`);const blob = await response.blob();Example response
HTTP/2 200 OKBinary body (not shown).
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |
Download report image ZIP
Section titled “Download report image ZIP”/v1/jobs/{id}/images.zip Use the exact image URL returned by a completed resource-image archive job.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | uuid | Job ID returned by submission. |
Example request
curl -sS -o output.bin "http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001/images.zip" \ -H "Authorization: Bearer ${localToken}"const response = await fetch("http://127.0.0.1:8765/v1/jobs/00000000-0000-4000-8000-000000000001/images.zip", { headers: { Authorization: `Bearer ${localToken}`, },});if (!response.ok) throw new Error(`HTTP ${response.status}`);const blob = await response.blob();Example response
HTTP/2 200 OKBinary body (not shown).
Errors
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | An ID in the path or query is malformed. |
401 | unauthorized | Supply the local Bearer token. |
403 | origin_not_allowed | Call from a local client or script. |
404 | not_found | Unknown region or record. |
404 | job_not_found | Job expired or was removed. |
409 | image_not_ready | Wait for image completion. |
413 | body_too_large | Request exceeds 2 MiB. |
429 | rate_limit_exceeded | Too many requests for this key; honour Retry-After when present. |
429 | queue_full | Wait for an active job or delete expired results. |