{"openapi":"3.1.0","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"Doitong Models API","version":"2026-10-20","summary":"Image, video, audio and other AI models behind one REST interface, priced like the upstream in USD.","description":"One POST /run/{model} for every model (add ?wait= to get the result in the same call), one GET /requests/{id} for status, exact prices from POST /quote/{model}, output files on our storage (kept forever, paid per GB-month, or 7 days for free: the account setting or ?storage=) and signed webhooks. Model ids contain slashes; they are written as is in the path. Prices are API credits paid from the account's API balance: 1000 API credits = 1 USD, every price object carries the USD amount (add ?currency=rub for roubles). Typed per-model paths: this document carries the featured models by default; add ?category=<id>, ?model=<id> or ?models=all for others (the generic /run/{model_id} accepts every model of GET /models).","contact":{"name":"Doitong","url":"https://doitong.com/developers"}},"servers":[{"url":"https://api.doitong.com/v1","description":"Doitong API"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Models","description":"The model catalog."},{"name":"Run","description":"Quote and run models."},{"name":"Requests","description":"Status, results and cancellation of runs."},{"name":"Files","description":"Upload input files."},{"name":"Account","description":"API balance (API credits), key limits and file storage."},{"name":"MCP","description":"Model Context Protocol endpoint for AI agents."}],"paths":{"/models":{"get":{"operationId":"listModels","tags":["Models"],"summary":"List models","security":[],"parameters":[{"name":"q","in":"query","required":false,"description":"Words that must all appear in the id, name, maker or tags.","schema":{"type":"string"}},{"name":"category","in":"query","required":false,"description":"Category id.","schema":{"type":"string","enum":["text-to-image","image-to-image","text-to-video","image-to-video","reference-to-video","video-to-video","lipsync","upscale","background-removal","text-to-speech","speech-to-text","text-to-music","audio","video-to-audio","image-to-3d","text-to-3d","3d","training","llm","vision","other"]}},{"name":"lab","in":"query","required":false,"description":"Model maker, by name or slug (any case).","schema":{"type":"string"}},{"name":"family","in":"query","required":false,"description":"Variants group id (the family field of a model).","schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"description":"Price mode.","schema":{"type":"string","enum":["exact","measured","estimate","metered"]}},{"$ref":"#/components/parameters/Limit"},{"name":"cursor","in":"query","required":false,"description":"next_cursor of the previous page.","schema":{"type":"string"}},{"$ref":"#/components/parameters/Currency"}],"responses":{"200":{"description":"A page of models.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelList"}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/models/{model_id}":{"get":{"operationId":"getModel","tags":["Models"],"summary":"Get a model","security":[],"parameters":[{"$ref":"#/components/parameters/ModelId"},{"$ref":"#/components/parameters/Currency"}],"responses":{"200":{"description":"The model.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelDetail"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/categories":{"get":{"operationId":"listCategories","tags":["Models"],"summary":"List categories","security":[],"responses":{"200":{"description":"Categories that have models.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CategoryList"}}}}}}},"/quote/{model_id}":{"post":{"operationId":"quoteModel","tags":["Run"],"summary":"Quote a run of any model","description":"Same body as run; returns the exact API credits and USD. A key is optional; with one the answer also says whether the API balance and the key can pay.","security":[{},{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/ModelId"},{"$ref":"#/components/parameters/Currency"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelInput"}}}},"responses":{"200":{"description":"The exact price.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}},"/run/{model_id}":{"post":{"operationId":"runModel","tags":["Run"],"summary":"Run any model","parameters":[{"$ref":"#/components/parameters/ModelId"},{"$ref":"#/components/parameters/Wait"},{"name":"webhook_url","in":"query","required":false,"description":"https URL that receives a signed POST when the request finishes.","schema":{"type":"string","format":"uri"}},{"name":"storage","in":"query","required":false,"description":"Where the output files go: permanent (kept until deleted, paid per GB-month) or temporary (free, deleted after 7 days). Default: the account setting (GET /account → storage.mode).","schema":{"$ref":"#/components/schemas/StorageMode"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Same key + same body returns the same request instead of a second charge.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelInput"}}}},"responses":{"200":{"description":"Finished within wait, or an idempotent replay.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"202":{"description":"Accepted; poll GET /requests/{id}.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"402":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"502":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/requests":{"get":{"operationId":"listRequests","tags":["Requests"],"summary":"List this account's requests","parameters":[{"$ref":"#/components/parameters/Limit"},{"name":"status","in":"query","required":false,"description":"Only this status.","schema":{"$ref":"#/components/schemas/RequestStatus"}},{"name":"model","in":"query","required":false,"description":"Only this model id.","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"next_cursor of the previous page.","schema":{"type":"string"}}],"responses":{"200":{"description":"Newest first.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestList"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/requests/{request_id}":{"get":{"operationId":"getRequest","tags":["Requests"],"summary":"Get a request","parameters":[{"$ref":"#/components/parameters/RequestId"},{"$ref":"#/components/parameters/Wait"},{"name":"logs","in":"query","required":false,"description":"Set to 1 to include the latest log lines.","schema":{"type":"string","enum":["0","1"]}}],"responses":{"200":{"description":"The request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"404":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/requests/{request_id}/cancel":{"post":{"operationId":"cancelRequest","tags":["Requests"],"summary":"Cancel a request","parameters":[{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"Canceled (refunded), or already canceled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelResult"}}}},"202":{"description":"The model is already working; cancellation was requested.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelResult"}}}},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/requests/{request_id}/files":{"delete":{"operationId":"deleteRequestFiles","tags":["Requests"],"summary":"Delete a request's output files","description":"Deletes our copies of the output files now and stops their storage charge. The request keeps its URLs with storage.expired = true. Idempotent; a request still running is a 409.","parameters":[{"$ref":"#/components/parameters/RequestId"}],"responses":{"200":{"description":"The request, files deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Request"}}}},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/files":{"post":{"operationId":"createUpload","tags":["Files"],"summary":"Create an upload URL","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadRequest"}}}},"responses":{"201":{"description":"Upload with PUT, then pass file_url as a model input.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"422":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/account":{"get":{"operationId":"getAccount","tags":["Account"],"summary":"API balance and key limits","parameters":[{"$ref":"#/components/parameters/Currency"}],"responses":{"200":{"description":"The account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/account/storage":{"patch":{"operationId":"updateStorageSettings","tags":["Account"],"summary":"Set the default file storage","description":"permanent (default): output files are kept until you delete them, 100 API credits per GB per month from the API balance. temporary: free, deleted after 7 days. Applies to new requests; ?storage= on a run overrides it.","parameters":[{"$ref":"#/components/parameters/Currency"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageSettingsUpdate"}}}},"responses":{"200":{"description":"The storage settings.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorageSettings"}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/mcp":{"post":{"operationId":"mcp","tags":["MCP"],"summary":"MCP endpoint (JSON-RPC 2.0, Streamable HTTP)","description":"Tools: search_models, get_model, quote, run, get_request, cancel_request, list_requests, create_upload, get_account.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcRequest"}}}},"responses":{"200":{"description":"JSON-RPC response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}},"202":{"description":"Notification accepted (no body)."},"401":{"description":"No API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcResponse"}}}}}}},"/run/lora":{"post":{"operationId":"runLora","tags":["Run"],"summary":"Run Stable Diffusion with LoRAs","description":"Text-to-image with any Stable Diffusion base model plus LoRAs, embeddings, ControlNets and IP adapters Price: $0.057 / image.","parameters":[{"$ref":"#/components/parameters/Wait"},{"name":"webhook_url","in":"query","required":false,"description":"https URL that receives a signed POST when the request finishes.","schema":{"type":"string","format":"uri"}},{"name":"storage","in":"query","required":false,"description":"Where the output files go: permanent (kept until deleted, paid per GB-month) or temporary (free, deleted after 7 days). Default: the account setting (GET /account → storage.mode).","schema":{"$ref":"#/components/schemas/StorageMode"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Same key + same body returns the same request instead of a second charge.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoraInput"}}}},"responses":{"200":{"description":"Finished within wait, or an idempotent replay.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Request"},{"type":"object","properties":{"output":{"anyOf":[{"$ref":"#/components/schemas/LoraOutput"},{"type":"null"}]}}}]}}}},"202":{"description":"Accepted; poll GET /requests/{id}.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Request"},{"type":"object","properties":{"output":{"anyOf":[{"$ref":"#/components/schemas/LoraOutput"},{"type":"null"}]}}}]}}}},"402":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"502":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"}}}},"/quote/lora":{"post":{"operationId":"quoteLora","tags":["Run"],"summary":"Quote Stable Diffusion with LoRAs","description":"Price: $0.057 / image.","security":[{},{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoraInput"}}}},"responses":{"200":{"description":"The exact price.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"404":{"$ref":"#/components/responses/Error"},"422":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key (doitong_…) as \"Authorization: Bearer <key>\". \"X-API-Key: <key>\" also works."}},"parameters":{"ModelId":{"name":"model_id","in":"path","required":true,"description":"Model id; may contain slashes (e.g. flux/schnell), written as is.","schema":{"type":"string"}},"RequestId":{"name":"request_id","in":"path","required":true,"schema":{"type":"string","pattern":"^req_[a-z0-9]+$"}},"Limit":{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},"Currency":{"name":"currency","in":"query","required":false,"description":"rub adds rouble amounts (rate × 1.3) next to USD; usd leaves them out. Default: rub on api.doitong.ru and doitong.ru, usd elsewhere.","schema":{"type":"string","enum":["usd","rub"]}},"Wait":{"name":"wait","in":"query","required":false,"description":"Hold the call up to this many seconds (max 20) and return the finished request if it completes in time.","schema":{"type":"number","minimum":0,"maximum":20}}},"responses":{"Error":{"description":"Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"ModelInput":{"type":"object","additionalProperties":true,"description":"The model's parameters. See GET /models/{model_id} for its input_schema."},"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["type","code","message"],"properties":{"type":{"type":"string","enum":["invalid_request","authentication_error","permission_error","not_found","insufficient_credits","budget_exceeded","conflict","rate_limited","upstream_error","service_unavailable","internal_error"]},"code":{"type":"string"},"message":{"type":"string"},"param":{"type":["string","null"]},"details":{"type":"array","items":{"type":"object","properties":{"param":{"type":"string"},"message":{"type":"string"}}}},"request_id":{"type":["string","null"]},"doc_url":{"type":"string","format":"uri"}}}}},"Price":{"type":"object","description":"Unit price. 1000 API credits = 1 USD (the upstream price).","properties":{"credits":{"type":["number","null"],"description":"API credits per unit (exact prices may have decimals)."},"usd":{"type":["string","null"],"description":"USD per unit, e.g. \"0.112\"."},"rub":{"type":"string","description":"RUB per unit, only with currency=rub or on the RU hosts."},"unit":{"type":"string"},"from_credits":{"type":["integer","null"],"description":"Cheapest plausible single run, in API credits. For a metered model (charged by usage): the typical run, never above hold_credits; a run can settle lower."},"from_usd":{"type":["string","null"]},"from_rub":{"type":"string"},"display":{"type":["string","null"],"description":"e.g. \"$0.112 / second\"."},"credits_display":{"type":["string","null"],"description":"e.g. \"112 API credits / second\"."},"rub_display":{"type":"string","description":"e.g. \"≈ 14.56 ₽ / секунду\" (RU only)."},"mode":{"type":["string","null"],"enum":["exact","measured","estimate","metered",null],"description":"exact: the price is computed from the input; measured: from the length / size of the input files, read before the run; estimate: a flat price per run. All are what a run charges (POST /quote returns the exact amount). metered: charged by actual usage (tokens, seconds of generated speech, processing time) at this unit price — a run holds hold_credits at most and the rest is refunded after it."},"hold_credits":{"type":"integer","description":"metered only: the most a run with the default input can cost (POST /quote gives it for your input)."},"hold_usd":{"type":"string"},"typical_credits":{"type":"integer","description":"metered only: a typical run."},"typical_usd":{"type":"string"},"per":{"type":"string","description":"measured only: what the unit is counted on, e.g. input_video, input_audio, output_video, output_image."},"label":{"type":"string","description":"measured: e.g. \"Price per second of your input video\"; metered: \"Charged by usage\"."}}},"Model":{"type":"object","required":["id","name","category"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"lab":{"type":"string"},"category":{"type":"string"},"summary":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"output_kind":{"type":"string"},"thumbnail_url":{"type":["string","null"]},"price":{"$ref":"#/components/schemas/Price"},"docs_url":{"type":"string","format":"uri"},"family":{"type":["string","null"],"description":"Variants group (GET /models?family=)."}}},"ModelDetail":{"allOf":[{"$ref":"#/components/schemas/Model"},{"type":"object","properties":{"description":{"type":"string"},"family":{"type":["string","null"]},"input_schema":{"type":"object"},"output_schema":{"type":"object"},"required_params":{"type":"array","items":{"type":"string"}},"aliases":{"type":"object","additionalProperties":{"type":"string"}},"pricing":{"type":"object"},"example_input":{"type":"object"},"family_ids":{"type":"array","items":{"type":"string"}},"markdown_url":{"type":"string","format":"uri"}}}]},"ModelList":{"type":"object","required":["object","data"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Model"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"Category":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"count":{"type":"integer"}}},"CategoryList":{"type":"object","required":["object","data"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Category"}}}},"Quote":{"type":"object","required":["object","model","credits"],"properties":{"object":{"const":"quote"},"model":{"type":"string"},"credits":{"type":"integer","description":"API credits this run charges (1000 = 1 USD)."},"usd":{"type":"string","description":"The same amount in USD, e.g. \"0.56\"."},"rub":{"type":"string","description":"In roubles (rate × 1.3), only with currency=rub or on the RU hosts."},"unit":{"type":"string"},"quantity":{"type":"number"},"unit_credits":{"type":"number"},"mode":{"enum":["exact","measured","estimate","metered"],"description":"exact: priced from the input. measured: priced from the length / size of the input files, which were measured for this quote (see measurements; a run with the same files within an hour charges this). estimate: a flat price per run from the typical cost of this model. All are exactly what the run charges. metered: credits is the HOLD — the most this run can cost, debited when it starts; after the run it is settled to the actual usage and the rest is refunded automatically (see hold, typical, and the request's cost.settled)."},"hold":{"type":"object","description":"metered only: { credits, usd (, rub) } — the most the run can cost."},"typical":{"type":["object","null"],"description":"metered only: { credits, usd (, rub) } of a typical run."},"settlement":{"const":"usage","description":"metered only: the run is charged its actual usage."},"label":{"type":"string","description":"\"Price per run\", \"Estimated price per run\" or, measured, e.g. \"Price per second of your input video\"."},"measurements":{"type":"object","description":"measured only: per input param what was measured ({ seconds, width, height, fps, frames, kind })."},"display":{"type":["string","null"]},"breakdown":{"type":["string","null"]},"input":{"type":"object","description":"The normalized input that was priced."},"warnings":{"type":"array","items":{"type":"string"}},"balance_credits":{"type":"integer","description":"API balance in API credits. Only with an API key."},"balance_usd":{"type":"string","description":"Only with an API key."},"affordable":{"type":"boolean","description":"Only with an API key."},"key_budget_remaining":{"type":["integer","null"],"description":"Only with an API key; API credits; null when the key has no cap."},"top_up_url":{"type":"string","format":"uri","description":"Present when the API balance is too low."}}},"RequestStatus":{"type":"string","enum":["queued","running","succeeded","failed","canceled"]},"Output":{"type":"object","required":["type","url"],"properties":{"type":{"type":"string","enum":["image","video","audio","file","3d"]},"url":{"type":"string","format":"uri"},"content_type":{"type":["string","null"]},"file_size":{"type":["integer","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"duration":{"type":["number","null"]},"stored":{"type":"boolean"},"expired":{"type":"boolean","description":"Present (true) once our copy was deleted; the URL no longer works."}}},"StorageMode":{"type":"string","enum":["permanent","temporary"]},"StorageSettingsUpdate":{"type":"object","required":["mode"],"additionalProperties":false,"properties":{"mode":{"$ref":"#/components/schemas/StorageMode"}}},"RequestStorage":{"type":"object","description":"Where the output files are kept (DESIGN.md §17).","properties":{"mode":{"$ref":"#/components/schemas/StorageMode"},"bytes":{"type":"integer","description":"Bytes of our copies of the output files."},"expires_at":{"type":["string","null"],"format":"date-time","description":"When the files are deleted (temporary); null when kept until you delete them."},"expired":{"type":"boolean","description":"true once the files were deleted."}}},"StorageSettings":{"type":"object","properties":{"object":{"type":"string","description":"\"storage_settings\" from PATCH /account/storage."},"mode":{"$ref":"#/components/schemas/StorageMode"},"price_credits_per_gb_month":{"type":"integer","description":"API credits per GB (1024^3 bytes) per month of permanent storage."},"price_usd_per_gb_month":{"type":"string"},"price_rub_per_gb_month":{"type":"string","description":"Only with currency=rub or on the RU hosts."},"temporary_retention_days":{"type":"integer"},"used_bytes":{"type":"integer","description":"Bytes kept permanently (billed)."},"used_gb":{"type":"string"},"expiring_bytes":{"type":"integer","description":"Bytes waiting to be deleted."},"monthly_estimate_credits":{"type":"integer"},"monthly_estimate_usd":{"type":"string"},"grace_started_at":{"type":["string","null"],"format":"date-time","description":"The API balance stopped covering storage at this time."},"grace_until":{"type":["string","null"],"format":"date-time","description":"Top up before this time, or the permanent files become temporary."}}},"Request":{"type":"object","required":["id","object","model","status"],"properties":{"id":{"type":"string"},"object":{"const":"request"},"model":{"type":"string"},"status":{"$ref":"#/components/schemas/RequestStatus"},"created_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"queue_position":{"type":["integer","null"]},"cost":{"type":"object","description":"API credits (1000 = 1 USD).","properties":{"credits":{"type":"integer","description":"The quoted price (metered: the hold)."},"usd":{"type":"string","description":"The quoted price in USD."},"charged":{"type":"integer","description":"Debited from the API balance."},"refunded":{"type":"integer","description":"Given back (failure, cancel, or the unused part of a metered hold)."},"mode":{"const":"metered","description":"Only on metered requests."},"held":{"type":"integer","description":"metered only: the hold debited at the start."},"typical":{"type":"integer","description":"metered only: a typical run, API credits."},"settled":{"type":["object","null"],"description":"metered only, once the request succeeded: status settled (credits = what the usage cost = charged − refunded), pending, or no_usage (the model reported no usage: the hold stands).","properties":{"status":{"enum":["settled","pending","no_usage"]},"credits":{"type":"integer"},"usd":{"type":"string"},"quantity":{"type":"number","description":"Usage units billed."},"unit":{"type":"string","description":"e.g. 1000_tokens, audio_second, compute_second."},"unit_usd":{"type":"string"},"source":{"enum":["billed_usage","processing_time"]},"approximate":{"type":"boolean","description":"true when measured from the processing time."}}}}},"input":{"type":"object"},"output":{"type":["object","null"]},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/Output"}},"error":{"anyOf":[{"type":"object","properties":{"type":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}}},{"type":"null"}]},"metrics":{"type":["object","null"]},"storage":{"$ref":"#/components/schemas/RequestStorage"},"logs":{"type":"array","items":{"type":"object"}},"urls":{"type":"object","properties":{"self":{"type":"string","format":"uri"},"cancel":{"type":"string","format":"uri"}}}}},"RequestList":{"type":"object","required":["object","data"],"properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Request"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"CancelResult":{"allOf":[{"$ref":"#/components/schemas/Request"},{"type":"object","properties":{"cancel_requested":{"type":"boolean"}}}]},"UploadRequest":{"type":"object","required":["filename"],"properties":{"filename":{"type":"string","description":"The extension decides the type (jpg, png, webp, mp4, mov, webm)."},"content_type":{"type":"string"},"size":{"type":"integer","minimum":1,"description":"Bytes."}}},"Upload":{"type":"object","properties":{"object":{"const":"upload"},"upload_url":{"type":"string","format":"uri"},"file_url":{"type":"string","format":"uri"},"method":{"const":"PUT"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"content_type":{"type":"string"},"expires_in":{"type":"integer"},"max_bytes":{"type":"integer"}}},"Account":{"type":"object","properties":{"object":{"const":"account"},"credits":{"type":"integer","description":"API balance in API credits (1000 = 1 USD). Separate from the Doitong app credits."},"balance":{"type":"object","properties":{"credits":{"type":"integer"},"usd":{"type":"string"},"rub":{"type":"string","description":"Only with currency=rub or on the RU hosts."}}},"top_up_url":{"type":"string","format":"uri"},"key":{"type":"object","properties":{"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"budget_remaining":{"type":["integer","null"],"description":"API credits; null: no cap on the key, the API balance is the limit."},"rate_limit":{"type":"integer"},"rate_limit_remaining":{"type":"integer"}}},"webhook_signing_secret":{"type":"string","description":"HMAC-SHA256 secret of the Doitong-Signature header."},"storage":{"$ref":"#/components/schemas/StorageSettings"}}},"JsonRpcRequest":{"type":"object","required":["jsonrpc","method"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","integer","null"]},"method":{"type":"string"},"params":{"type":"object"}}},"JsonRpcResponse":{"type":"object","required":["jsonrpc"],"properties":{"jsonrpc":{"const":"2.0"},"id":{"type":["string","integer","null"]},"result":{"type":"object"},"error":{"type":"object"}}},"LoraInput":{"if":{"properties":{"ip_adapter":{"minItems":1}},"required":["ip_adapter"]},"properties":{"clip_skip":{"default":0,"description":"Skips a portion of image generation to render faster, producing slightly different results.","maximum":2,"minimum":0,"title":"Clip Skip","type":"integer"},"controlnet_guess_mode":{"default":false,"description":"Restricts ControlNet application to conditional predictions when true.","title":"Controlnet Guess Mode","type":"boolean"},"controlnets":{"default":[],"description":"Control nets scheduled for application to the image at specified timesteps during generation, with no limit on how many you supply.","items":{"properties":{"conditioning_scale":{"default":1,"description":"Scaling applied to ControlNet weights before they are merged into the base model.","maximum":2,"minimum":0,"title":"Conditioning Scale","type":"number"},"config_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional URL pointing to the ControlNet's config.json file.","title":"Config Url"},"end_percentage":{"default":1,"description":"Percentage of total timesteps at which ControlNet stops influencing image generation.","maximum":1,"minimum":0,"title":"End Percentage","type":"number"},"image_url":{"description":"Image URL supplied as the ControlNet input.","title":"Image Url","type":"string"},"ip_adapter_index":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"IP adapter selection by index for an InstantID ControlNet; other ControlNets do not need this setting.","title":"Ip Adapter Index"},"mask_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ControlNet mask, which must match the control image in size when supplied; width and height must each be divisible by 32.","title":"Mask Url"},"path":{"description":"ControlNet weight location, specified as a URL or path.","title":"Path","type":"string"},"start_percentage":{"default":0,"description":"Percentage of total timesteps at which ControlNet starts influencing image generation.","maximum":1,"minimum":0,"title":"Start Percentage","type":"number"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional variant for use with a Hugging Face repository key.","title":"Variant"}},"required":["path","image_url"],"title":"ControlNet","type":"object","x-doitong-order":["path","config_url","variant","image_url","mask_url","conditioning_scale","start_percentage","end_percentage","ip_adapter_index"]},"title":"Controlnets","type":"array"},"debug_latents":{"default":false,"description":"Saves latents for debugging when true.","title":"Debug Latents","type":"boolean"},"debug_per_pass_latents":{"default":false,"description":"Enable per-pass debugging by setting this to true, which saves the latents from every pass.","title":"Debug Per Pass Latents","type":"boolean"},"embeddings":{"default":[],"description":"Embeddings applied during image generation to map prompt tokens to embedding weights. Currently, only one embedding is supported.","items":{"properties":{"path":{"description":"Embedding weights specified by URL or file path.","title":"Path","type":"string"},"tokens":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"description":"Prompt tokens mapped to embedding weights. Omitting them creates one token per embedding-file vector, named <s0>, <s1>, ...; use the mapped tokens in your prompts.","title":"Tokens"}},"required":["path"],"title":"Embedding","type":"object","x-doitong-order":["path","tokens"]},"title":"Embeddings","type":"array"},"enable_safety_checker":{"default":false,"description":"Safety checker activation; true enables checking.","title":"Enable Safety Checker","type":"boolean"},"eta":{"default":0,"description":"Eta setting used when generating images.","maximum":1,"minimum":0,"title":"Eta","type":"number"},"guidance_scale":{"default":7.5,"description":"Prompt-adherence strength for image selection, expressed as CFG (Classifier Free Guidance).","maximum":20,"minimum":0,"title":"Guidance scale (CFG)","type":"number"},"ic_light_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Input image URL for generation with the IC Light model.","title":"Ic Light Image Url"},"ic_light_model_background_image_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Model-compatible background for IC Light image generation, supplied as an image URL.","title":"Ic Light Model Background Image Url"},"ic_light_model_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IC Light model URL used when generating images.","title":"Ic Light Model Url"},"image_encoder_path":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Image encoder specified by an HTTPS URL or Hugging Face ID, with compatibility determined by the IP-Adapter weights: SD1.5 uses image_encoder_subfolder='models/image_encoder', while h94/IP-Adapter SDXL uses h94/IP-Adapter and image_encoder_subfolder='sdxl_models/image_encoder'. An encoder is required whenever ip_adapter contains a value.","title":"Image Encoder Path"},"image_encoder_subfolder":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Subdirectory within image_encoder_path that holds the image encoder weights.","title":"Image Encoder Subfolder"},"image_encoder_weight_name":{"anyOf":[{"type":"string"},{"type":"null"}],"default":"pytorch_model.bin","description":"Select the image encoder's weights by name for use in generating images.","examples":["pytorch_model.bin"],"title":"Image Encoder Weight Name"},"image_format":{"default":"png","description":"File format for the resulting image.","enum":["jpeg","png"],"examples":["jpeg"],"title":"Image Format","type":"string"},"image_size":{"anyOf":[{"properties":{"height":{"default":512,"description":"The height of the generated image.","exclusiveMinimum":0,"maximum":14142,"title":"Height","type":"integer"},"width":{"default":512,"description":"The width of the generated image.","exclusiveMinimum":0,"maximum":14142,"title":"Width","type":"integer"}},"title":"ImageSize","type":"object","x-doitong-order":["width","height"]},{"enum":["square_hd","square","portrait_4_3","portrait_16_9","landscape_4_3","landscape_16_9"],"type":"string"},{"type":"null"}],"default":"square_hd","description":"Output image dimensions, selected from presets or specified as custom width and height. Both custom dimensions must be divisible by 8.","title":"Image Size"},"ip_adapter":{"default":[],"description":"IP adapters used to generate images. Providing any entries requires image_encoder_path.","items":{"properties":{"image_projection_shortcut":{"default":true,"description":"Image projection shortcut setting, with True as the default. Use False for FaceID plus V1 models and True for FaceID plus V2 models.","title":"Image Projection Shortcut","type":"boolean"},"insight_face_model_path":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"InsightFace model weights location, specified as a URL or path.","title":"Insight Face Model Path"},"ip_adapter_image_url":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}],"description":"Image URL supplied as the IP adapter input.","title":"Ip Adapter Image Url"},"ip_adapter_mask_url":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IP adapter mask, subject to a size constraint when supplied: its dimensions must equal those of the adapter image.","title":"Ip Adapter Mask Url"},"model_subfolder":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"IP adapter weight location, specified as a subfolder within the model directory.","title":"Model Subfolder"},"path":{"description":"IP adapter weights location, specified as a URL or path.","title":"Path","type":"string"},"scale":{"default":1,"description":"Scaling factor for IP adapter weights, applied before they are merged into the base model.","minimum":0,"title":"Scale","type":"number"},"scale_json":{"anyOf":[{"type":"object"},{"type":"null"}],"description":"Scaling factor for IP adapter weights, applied before they are merged into the base model.","title":"Scale Json"},"unconditional_noising_factor":{"default":0,"description":"Factor controlling unconditional noising for the IP adapter.","maximum":1,"minimum":0,"title":"Unconditional Noising Factor","type":"number"},"weight_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filename of the weights.","title":"Weight Name"}},"required":["ip_adapter_image_url","path"],"title":"IPAdapter","type":"object","x-doitong-order":["ip_adapter_image_url","ip_adapter_mask_url","path","model_subfolder","weight_name","insight_face_model_path","scale","scale_json","unconditional_noising_factor","image_projection_shortcut"]},"title":"Ip Adapter","type":"array"},"loras":{"default":[],"description":"LoRAs whose combined effect produces the generated image, with no limit on how many you supply.","items":{"properties":{"path":{"description":"Location of the LoRA weights, specified as a URL or path.","title":"Path","type":"string"},"scale":{"default":1,"description":"Multiplier applied to the LoRA weight before it is merged into the base model.","maximum":4,"minimum":0,"title":"Scale","type":"number"}},"required":["path"],"title":"LoraWeight","type":"object","x-doitong-order":["path","scale"]},"title":"Loras","type":"array"},"model_name":{"description":"Base model for generating the image, identified by either a URL or a HuggingFace ID.","examples":["stabilityai/stable-diffusion-xl-base-1.0","runwayml/stable-diffusion-v1-5","SG161222/Realistic_Vision_V2.0"],"title":"Model Name","type":"string"},"negative_prompt":{"default":"","description":"Negative prompt specifying unwanted image details. It can exclude colors, objects, scenery, or finer features and qualities, such as a moustache, blur, or low resolution.","examples":["cartoon, painting, illustration, worst quality, low quality, normal quality"],"title":"Negative Prompt","type":"string"},"num_images":{"default":1,"description":"Set how many images a single request produces, allowing more generation time for a larger batch.","maximum":8,"minimum":1,"title":"Number of images","type":"integer","x-doitong-alias":"num_outputs"},"num_inference_steps":{"default":30,"description":"Control how many generation steps Stable Diffusion performs; additional steps may yield a more detailed final image.","maximum":150,"minimum":1,"title":"Number of inference steps","type":"integer"},"prediction_type":{"default":"epsilon","description":"Choose the prediction type for generating images; without a different selection, `epsilon` is used.","enum":["v_prediction","epsilon"],"title":"Prediction Type","type":"string"},"prompt":{"description":"Describe the image you want generated, using as much detail as possible to get the best results.","examples":["Photo of a european medieval 40 year old queen, silver hair, highly detailed face, detailed eyes, head shot, intricate crown, age spots, wrinkles","Photo of a classic red mustang car parked in las vegas strip at night"],"title":"Prompt","type":"string"},"prompt_weighting":{"default":false,"description":"Prompt-weighting toggle: true removes the 77 token limit through embedding averaging and enables weighting syntax.","examples":[true],"title":"Prompt Weighting","type":"boolean"},"rescale_betas_snr_zero":{"default":false,"description":"Controls whether the sampler enables rescale_betas_snr_zero.","title":"Rescale Betas Snr Zero","type":"boolean"},"scheduler":{"anyOf":[{"enum":["DPM++ 2M","DPM++ 2M Karras","DPM++ 2M SDE","DPM++ 2M SDE Karras","Euler","Euler A","Euler (trailing timesteps)","LCM","LCM (trailing timesteps)","DDIM","TCD"],"type":"string"},{"type":"null"}],"description":"Scheduler or sampler used to denoise the image.","title":"Scheduler"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Seed for reproducing images in Stable Diffusion. An image can be reproduced exactly on every run by keeping the model version, prompt, and seed unchanged.","title":"Seed"},"sigmas":{"default":{"array":[],"method":"default"},"description":"Denoising sigma schedule override, mutually exclusive with timesteps. Without an override—the default—the scheduler calculates sigmas from num_inference_steps; supplying a custom schedule makes num_inference_steps irrelevant. An override requires scheduler support for the sigmas argument to set_sigmas.","properties":{"array":{"default":[],"description":"Sigma schedule applied when the selected method is 'custom'.","items":{"type":"number"},"title":"Array","type":"array"},"method":{"default":"default","description":"Choose how sigmas are determined: 'default', the default setting, uses the scheduler's own sigma values. To supply a sigma schedule yourself, select 'custom' and place the schedule in the `array` field.","enum":["default","array"],"title":"Method","type":"string"}},"title":"SigmasInput","type":"object","x-doitong-order":["method","array"]},"tile_height":{"default":4096,"description":"Set how large each tile is during image generation.","maximum":4096,"minimum":128,"title":"Tile Height","type":"integer"},"tile_stride_height":{"default":2048,"description":"Set the spacing between successive tile positions during image generation.","maximum":2048,"minimum":64,"title":"Tile Stride Height","type":"integer"},"tile_stride_width":{"default":2048,"description":"Set the spacing between successive tile positions during image generation.","maximum":2048,"minimum":64,"title":"Tile Stride Width","type":"integer"},"tile_width":{"default":4096,"description":"Set how large each tile is during image generation.","maximum":4096,"minimum":128,"title":"Tile Width","type":"integer"},"timesteps":{"default":{"array":[],"method":"default"},"description":"Denoising timestep schedule override, mutually exclusive with sigmas. Without an override—the default—the scheduler calculates timesteps from num_inference_steps; supplying a custom schedule makes num_inference_steps irrelevant. An override requires scheduler support for the timesteps argument to set_timesteps.","properties":{"array":{"default":[],"description":"Timestep schedule applied when the selected method is 'custom'.","items":{"type":"integer"},"title":"Array","type":"array"},"method":{"default":"default","description":"Choose how timesteps are determined: 'default', the default setting, lets the scheduler use `num_inference_steps`. To supply a timestep schedule yourself, select 'array' and place the schedule in the `array` field.","enum":["default","array"],"title":"Method","type":"string"}},"title":"TimestepsInput","type":"object","x-doitong-order":["method","array"]},"unet_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Custom U-Net selection for generating images; supply either its HuggingFace ID or its URL.","title":"Unet Name"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"HuggingFace model variant selection; 'fp16' is one example.","title":"Variant"}},"required":["model_name","prompt"],"then":{"properties":{"image_encoder_path":{"minLength":1,"type":"string"}},"required":["image_encoder_path"]},"title":"TextToImageInput","type":"object","x-doitong-order":["model_name","unet_name","variant","prompt","negative_prompt","prompt_weighting","loras","embeddings","controlnets","controlnet_guess_mode","ip_adapter","image_encoder_path","image_encoder_subfolder","image_encoder_weight_name","ic_light_model_url","ic_light_model_background_image_url","ic_light_image_url","seed","image_size","num_inference_steps","guidance_scale","clip_skip","scheduler","timesteps","sigmas","prediction_type","rescale_betas_snr_zero","image_format","num_images","enable_safety_checker","tile_width","tile_height","tile_stride_width","tile_stride_height","eta","debug_latents","debug_per_pass_latents"]},"LoraOutput":{"properties":{"debug_latents":{"anyOf":[{"properties":{"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MIME type identifying the file's content.","examples":["image/png"],"title":"Content Type"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"File name, generated automatically when omitted.","examples":["z9RV14K95DvU.png"],"title":"File Name"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"File size measured in bytes.","examples":[4404019],"title":"File Size"},"url":{"description":"Download URL for the file.","title":"Url","type":"string"}},"required":["url"],"title":"File","type":"object","x-doitong-order":["url","content_type","file_name","file_size"]},{"type":"null"}],"description":"Latent data stored for debugging."},"debug_per_pass_latents":{"anyOf":[{"properties":{"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MIME type identifying the file's content.","examples":["image/png"],"title":"Content Type"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"File name, generated automatically when omitted.","examples":["z9RV14K95DvU.png"],"title":"File Name"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"File size measured in bytes.","examples":[4404019],"title":"File Size"},"url":{"description":"Download URL for the file.","title":"Url","type":"string"}},"required":["url"],"title":"File","type":"object","x-doitong-order":["url","content_type","file_name","file_size"]},{"type":"null"}],"description":"Per-pass latent data stored for debugging."},"has_nsfw_concepts":{"description":"Indicates whether NSFW concepts appear in the generated images.","items":{"type":"boolean"},"title":"Has Nsfw Concepts","type":"array"},"images":{"description":"File information for the generated images.","items":{"description":"Represents an image file.","properties":{"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"MIME type identifying the file's content.","examples":["image/png"],"title":"Content Type"},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"File name, generated automatically when omitted.","examples":["z9RV14K95DvU.png"],"title":"File Name"},"file_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"File size measured in bytes.","examples":[4404019],"title":"File Size"},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The height of the image in pixels.","examples":[1024],"title":"Height"},"url":{"description":"Download URL for the file.","title":"Url","type":"string"},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"The width of the image in pixels.","examples":[1024],"title":"Width"}},"required":["url"],"title":"Image","type":"object","x-doitong-order":["url","content_type","file_name","file_size","width","height"]},"title":"Images","type":"array"},"seed":{"description":"Image-generation seed, including the randomly chosen value if the input omitted a seed; otherwise, it repeats the supplied value.","title":"Seed","type":"integer"}},"required":["images","seed","has_nsfw_concepts","debug_latents","debug_per_pass_latents"],"title":"OutputParameters","type":"object","x-doitong-order":["images","seed","has_nsfw_concepts","debug_latents","debug_per_pass_latents"]}}}}