{"openapi":"3.1.0","info":{"title":"Draw API","version":"1.1.0","description":"Search, generate, convert and colour Learning Legendario-style illustrations. Human-readable docs: https://draw.milab.es/api-docs. MCP server: https://draw.milab.es/api/mcp."},"servers":[{"url":"https://draw.milab.es"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}},"schemas":{"Image":{"type":"object","properties":{"id":{"type":"string","description":"Permanent id; /i/{id}.webp never changes."},"url":{"type":"string","format":"uri"},"pngUrl":{"type":"string","format":"uri"},"thumbnailUrl":{"type":"string","format":"uri"},"topic":{"type":["string","null"]},"prompt":{"type":["string","null"]},"description":{"type":["string","null"],"description":"AI description used by the search index (EN / ES)."},"collections":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"}}},"Error":{"type":"object","properties":{"error":{"type":"string"}}}}},"security":[{"bearer":[]}],"paths":{"/api/v1/search":{"get":{"operationId":"searchIllustrations","summary":"Search illustrations by meaning (Spanish or English)","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","maxLength":500}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":12}},{"name":"collection","in":"query","schema":{"type":"string"},"description":"Collection name or id."}],"responses":{"200":{"description":"Matches, best first","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"count":{"type":"integer"},"results":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Image"},{"type":"object","properties":{"score":{"type":"number"},"similarity":{"type":["number","null"]}}}]}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/generate":{"post":{"operationId":"generateIllustration","summary":"Generate an illustration for a topic (30-160 s)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["topic"],"properties":{"topic":{"type":"string"},"quality":{"type":"string","enum":["low","medium","high"],"description":"Defaults to the token's quality."},"format":{"type":"string","enum":["png","webp","avif"],"description":"Defaults to the token's format."},"background":{"type":"string","enum":["original","white","transparent"],"description":"white = pure #ffffff paper; transparent is beta."},"reuse":{"type":"string","enum":["exact","similar","none"],"default":"exact"},"similarityThreshold":{"type":"number","minimum":0.3,"maximum":0.95,"default":0.55},"referenceImage":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Image URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"id":{"type":"string"},"cached":{"type":"boolean"},"similar":{"type":"boolean"},"similarity":{"type":"number"},"matchedTopic":{"type":"string"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/generate-link":{"get":{"operationId":"generateIllustrationLink","summary":"Generate via a plain GET URL (link key, no headers)","security":[],"parameters":[{"name":"topic","in":"query","required":true,"schema":{"type":"string","maxLength":300}},{"name":"key","in":"query","required":true,"schema":{"type":"string"},"description":"Link key (llk_…)."},{"name":"quality","in":"query","schema":{"type":"string","enum":["low","medium","high"],"description":"Defaults to the token's quality."}},{"name":"format","in":"query","schema":{"type":"string","enum":["png","webp","avif"],"description":"Defaults to the token's format."}},{"name":"background","in":"query","schema":{"type":"string","enum":["original","white","transparent"],"description":"white = pure #ffffff paper; transparent is beta."}}],"responses":{"200":{"description":"Image URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"id":{"type":"string"},"cached":{"type":"boolean"},"similar":{"type":"boolean"},"similarity":{"type":"number"},"matchedTopic":{"type":"string"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"429":{"description":"Rate limit reached","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/convert":{"post":{"operationId":"convertImage","summary":"Redraw a public image in the LL style","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["imageUrl"],"properties":{"imageUrl":{"type":"string","format":"uri"},"detail":{"type":"string","enum":["expanded","short"],"default":"expanded"},"description":{"type":"string"},"quality":{"type":"string","enum":["low","medium","high"],"description":"Defaults to the token's quality."},"format":{"type":"string","enum":["png","webp","avif"],"description":"Defaults to the token's format."},"background":{"type":"string","enum":["original","white","transparent"],"description":"white = pure #ffffff paper; transparent is beta."}}}}}},"responses":{"200":{"description":"Converted image","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"id":{"type":"string"},"description":{"type":"string"},"sourceImage":{"type":"string"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/colorize":{"post":{"operationId":"colorizeIllustration","summary":"Fill an illustration's background with a flat colour (no AI)","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["imageUrl"],"properties":{"imageUrl":{"type":"string","format":"uri"},"backgroundColor":{"type":"string","pattern":"^#[0-9a-fA-F]{6}$"},"format":{"type":"string","enum":["png","webp"]},"bgThreshold":{"type":"integer","minimum":140,"maximum":250},"inkThreshold":{"type":"integer","minimum":40,"maximum":200},"closeRadius":{"type":"integer","minimum":1,"maximum":40},"restoreRadius":{"type":"integer","minimum":1,"maximum":75},"organicRadius":{"type":"integer","minimum":0,"maximum":30},"smoothRadius":{"type":"integer","minimum":0,"maximum":30}}}}}},"responses":{"200":{"description":"Coloured copy"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/images/{id}":{"get":{"operationId":"getIllustration","summary":"One illustration by id","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Image","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Image"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"404":{"description":"Not found"},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/collections":{"get":{"operationId":"listCollections","summary":"All collections with image counts","responses":{"200":{"description":"Collections"},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Missing, invalid or revoked token","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"502":{"description":"Upstream (OpenAI / image fetch) failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/i/{file}":{"get":{"operationId":"imageFile","summary":"Stable public image URL: {id}.png | {id}.webp | {id}.avif","security":[],"parameters":[{"name":"file","in":"path","required":true,"schema":{"type":"string"}},{"name":"background","in":"query","schema":{"type":"string","enum":["original","white","transparent"]}}],"responses":{"302":{"description":"Redirect to the current file"},"404":{"description":"Unknown id"}}}}}}