{"openapi":"3.1.0","info":{"title":"Sable Designs","version":"1.1.0","description":"Make pictures and videos with Sable Designs. Every call spends from, and follows the rules of, the account that owns the key. Price a request with getPrice before generate, then poll getJob.","termsOfService":"https://sabledesigns.red/legal/terms"},"externalDocs":{"description":"Guides, webhooks, errors and the MCP server","url":"https://sabledesigns.red/developers"},"servers":[{"url":"https://sabledesigns.red/api/v1"}],"security":[{"key":[]},{"oauth":["read","generate"]}],"components":{"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["type","code","message"],"properties":{"type":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"},"status":{"type":"integer"},"request_id":{"type":["string","null"]}}}}},"Output":{"type":"object","required":["name","download_url"],"properties":{"name":{"type":"string"},"download_url":{"type":"string","description":"Needs the same Authorization header"},"open_url":{"type":"string","description":"Opens without a key for an hour (not for explicit results)"},"content_type":{"type":"string"},"explicit":{"type":"boolean"},"resource_uri":{"type":"string"}}},"Job":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"object":{"type":"string","enum":["job"]},"tool":{"type":["string","null"]},"status":{"type":"string","enum":["queued","running","collecting","done","failed","blocked","stopped","cancelled"]},"progress":{"type":["number","null"]},"created_at":{"type":["integer","null"]},"finished_at":{"type":["integer","null"]},"seconds":{"type":["number","null"]},"credits":{"type":["integer","null"]},"error":{"type":["string","null"]},"outputs":{"type":"array","items":{"$ref":"#/components/schemas/Output"}},"webhook":{"type":"object","properties":{"state":{"type":"string"},"attempts":{"type":"integer"}}}}},"JobList":{"type":"object","properties":{"object":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}},"Quote":{"type":"object","properties":{"credits":{"type":"integer"},"images":{"type":"integer"},"per_image":{"type":"integer"},"each_more":{"type":["integer","null"]},"balance":{"type":"integer"},"enough":{"type":"boolean"},"enforced":{"type":"boolean"}}},"Upload":{"type":"object","properties":{"object":{"type":"string"},"ref":{"type":"string"},"ok":{"type":"boolean"}}},"GenerateRequest":{"type":"object","required":["workflow"],"properties":{"workflow":{"type":"string","description":"A tool key from listTools, e.g. api_image"},"character":{"type":"string","description":"Optional: one of the account's characters, by name"},"params":{"type":"object","additionalProperties":true,"description":"prompt, scene, width, height, batch, image or video (a ref from an upload) and the tool's settings. api_image and api_video need model, a key from listModels."},"webhook_url":{"type":"string","format":"uri","description":"Optional https address called when the job finishes, signed to the Standard Webhooks spec"}}}},"responses":{"BadRequest":{"description":"The request is not valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"PaymentRequired":{"description":"Not enough credits, or the key's monthly limit is reached","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Not allowed for this key or account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"The tool is unavailable, or a request is still running","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unprocessable":{"description":"Refused by the content policy, or not processable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Too many requests; see Retry-After","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"securitySchemes":{"key":{"type":"http","scheme":"bearer","description":"A key from the Sable Account page"},"oauth":{"type":"oauth2","flows":{"authorizationCode":{"authorizationUrl":"https://sabledesigns.red/oauth/authorize","tokenUrl":"https://sabledesigns.red/oauth/token","refreshUrl":"https://sabledesigns.red/oauth/token","scopes":{"read":"See tools, characters, prices, balance and results","generate":"Make pictures and videos, spending credits"}}}}}},"paths":{"/me":{"get":{"operationId":"getAccount","summary":"Credit balance and this key's monthly limit","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false}},"/tools":{"get":{"operationId":"listTools","summary":"What Sable can make, with each tool's inputs, scenes and settings","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false}},"/models":{"get":{"operationId":"listModels","summary":"Models for the Image and Video Generator","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"parameters":[{"name":"kind","in":"query","required":false,"schema":{"type":"string","enum":["image","video"]}}]}},"/characters":{"get":{"operationId":"listCharacters","summary":"The account's characters","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false}},"/quote":{"post":{"operationId":"getPrice","summary":"What a request will cost, in credits. Spends nothing.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Quote"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}}}},"/generate":{"post":{"operationId":"generate","summary":"Start a picture or video. Spends credits.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":true,"description":"Returns the job at once. Poll getJob (with wait) until status is done, or pass webhook_url.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. Retrying with the same key never runs or charges twice.","schema":{"type":"string","maxLength":255}}]}},"/jobs":{"get":{"operationId":"listJobs","summary":"Recent jobs, newest first","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobList"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"after","in":"query","required":false,"schema":{"type":"string"},"description":"next_cursor from the previous page"}]}},"/jobs/{jid}":{"get":{"operationId":"getJob","summary":"A job's status and results","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"parameters":[{"name":"jid","in":"path","required":true,"schema":{"type":"string"}},{"name":"wait","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":50},"description":"Seconds to wait for it to finish before answering"}]}},"/jobs/{jid}/cancel":{"post":{"operationId":"cancelJob","summary":"Stop a job that is still running","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":true,"parameters":[{"name":"jid","in":"path","required":true,"schema":{"type":"string"}}]}},"/uploads/base64":{"post":{"operationId":"uploadFile","summary":"Upload a picture or video as base64. Returns a ref for params.image or params.video","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data_base64"],"properties":{"filename":{"type":"string"},"data_base64":{"type":"string"}}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. Retrying with the same key never runs or charges twice.","schema":{"type":"string","maxLength":255}}]}},"/uploads/url":{"post":{"operationId":"uploadFromUrl","summary":"Upload a picture or video from a public https address","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"filename":{"type":"string"}}}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Any unique string. Retrying with the same key never runs or charges twice.","schema":{"type":"string","maxLength":255}}]}},"/uploads/chatgpt":{"post":{"operationId":"uploadChatFiles","summary":"Upload pictures the user attached in ChatGPT. Returns refs","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"ref":{"type":"string"}}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"402":{"$ref":"#/components/responses/PaymentRequired"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"422":{"$ref":"#/components/responses/Unprocessable"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-openai-isConsequential":false,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["openaiFileIdRefs"],"properties":{"openaiFileIdRefs":{"type":"array","items":{"type":"string"}}}}}}}}}}}