{"openapi":"3.1.0","info":{"title":"Kirigami.ai Public API","version":"1.0.0","description":"Convert images to editable PowerPoint (.pptx) files, upload assets, publish to the gallery, and authenticate CLI tools.\n\n**Base URL:** `https://kirigami.ai`\n\n**Authentication:** Use the `X-Api-Key` header with a key starting with `ip2p_`. Obtain one at [Settings → API Keys](https://kirigami.ai/settings/api-keys).","contact":{"name":"Kirigami.ai support","url":"https://kirigami.ai"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://kirigami.app","description":"Production"}],"security":[{"apiKey":[]}],"tags":[{"name":"Conversions","description":"Convert images to PPTX and check job status"},{"name":"Uploads","description":"Upload images for conversion"},{"name":"Marketplace","description":"Browse and fetch gallery items"},{"name":"Publishing","description":"Publish drafts to the gallery"},{"name":"CLI Auth","description":"OAuth-like device code flow for CLI tools"}],"paths":{"/api/v1/convert":{"post":{"tags":["Conversions"],"summary":"Start image → PPTX conversion","description":"Queue a conversion job for one or more images. Returns a jobId to poll.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"images":{"minItems":1,"maxItems":50,"type":"array","items":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"HTTPS URL of the uploaded image"},"id":{"type":"string","minLength":1,"description":"Client-supplied unique ID for this image"}},"required":["url","id"],"additionalProperties":false},"description":"Images to convert to a single PPTX"},"filename":{"description":"Custom output filename (without extension auto-appended)","type":"string","maxLength":255},"removeText":{"default":true,"description":"Whether to remove existing text using AI before vectorization","type":"boolean"}},"required":["images","removeText"],"additionalProperties":false}}}},"responses":{"200":{"description":"Conversion job created","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"jobId":{"type":"string","description":"ID used to poll /api/v1/jobs/:jobId"},"message":{"type":"string"},"estimatedCredits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"totalImages":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"queuedImages":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"processingMode":{"type":"string","enum":["qstash","convex_cron"]}},"required":["success","jobId","message","estimatedCredits","totalImages","queuedImages","processingMode"],"additionalProperties":false}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"402":{"description":"Insufficient credits","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/jobs/{jobId}":{"get":{"tags":["Conversions"],"summary":"Get conversion job status","description":"Poll the status of a conversion job. When status = completed, downloadUrl is included.","security":[{"apiKey":[]}],"parameters":[{"name":"jobId","in":"path","required":true,"schema":{"type":"string"},"description":"Job ID returned from /api/v1/convert"}],"responses":{"200":{"description":"Job status","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"jobId":{"type":"string"},"status":{"type":"string","enum":["pending","waiting_images","processing","completed","failed","waiting_retry"]},"progress":{"type":"integer","minimum":0,"maximum":100},"currentStep":{"type":"string"},"progressMessage":{"type":"string"},"errorMessage":{"type":"string"},"downloadUrl":{"description":"Available when status = completed","type":"string","format":"uri"},"completedAt":{"description":"Unix ms timestamp, present when status = completed","type":"number"},"createdAt":{"type":"number","description":"Unix ms timestamp"}},"required":["success","jobId","status","progress","createdAt"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"404":{"description":"Job not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/upload":{"post":{"tags":["Uploads"],"summary":"Upload an image","description":"Upload an image for conversion. Returns a pre-signed URL (valid 7 days) to pass to /api/v1/convert. Supports both JSON (base64) and multipart/form-data.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"imageData":{"type":"string","minLength":1,"description":"Base64-encoded image data (data URI prefix is stripped automatically)"},"mimeType":{"default":"image/png","description":"MIME type, e.g. image/png","type":"string"},"filename":{"default":"upload.png","type":"string","maxLength":255}},"required":["imageData","mimeType","filename"],"additionalProperties":false}},"multipart/form-data":{"schema":{"type":"object","properties":{"image":{"type":"string","format":"binary"}},"required":["image"]}}}},"responses":{"200":{"description":"Image uploaded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"imageUrl":{"type":"string","format":"uri","description":"Pre-signed GET URL (valid for 7 days)"},"imageId":{"type":"string"},"r2Key":{"type":"string"},"size":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"mimeType":{"type":"string"}},"required":["success","imageUrl","imageId","r2Key","size","mimeType"],"additionalProperties":false}}}},"400":{"description":"Invalid request (missing field, oversized, or unsupported MIME)","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/marketplace":{"get":{"tags":["Marketplace"],"summary":"List published gallery items","security":[{"apiKey":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":40,"maximum":200}},{"name":"tag","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Item list","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"tags":{"default":[],"type":"array","items":{"type":"string"}},"previewImageUrl":{"type":"string","format":"uri"},"previewImageUrls":{"default":[],"type":"array","items":{"type":"string","format":"uri"}},"creatorName":{"default":"Anonymous","type":"string"},"viewCount":{"default":0,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likeCount":{"default":0,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"}},"required":["id","title","tags","previewImageUrls","creatorName","viewCount","likeCount","createdAt"],"additionalProperties":false}},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["success","items","count"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/marketplace/{itemId}":{"get":{"tags":["Marketplace"],"summary":"Get gallery item details","description":"Fetches full item details and records a view event.","security":[{"apiKey":[]}],"parameters":[{"name":"itemId","in":"path","required":true,"schema":{"type":"string"}},{"name":"source","in":"query","schema":{"type":"string","enum":["cli","mcp","api"],"default":"api"}}],"responses":{"200":{"description":"Item detail","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"item":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"tags":{"default":[],"type":"array","items":{"type":"string"}},"previewImageUrl":{"type":"string","format":"uri"},"previewImageUrls":{"default":[],"type":"array","items":{"type":"string","format":"uri"}},"creatorName":{"default":"Anonymous","type":"string"},"viewCount":{"default":0,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"likeCount":{"default":0,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"createdAt":{"type":"string"},"bookmarkCount":{"default":0,"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"updatedAt":{"type":"string"}},"required":["id","title","tags","previewImageUrls","creatorName","viewCount","likeCount","createdAt","bookmarkCount","updatedAt"],"additionalProperties":false},"viewRecorded":{"type":"boolean"}},"required":["success","item","viewRecorded"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"404":{"description":"Item not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/publish":{"post":{"tags":["Publishing"],"summary":"Publish a draft to the gallery","description":"Publishes a slide (and metadata) as a draft to the gallery. You must first upload images via /api/v1/upload.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"title":{"type":"string","minLength":1,"maxLength":200},"description":{"default":"","type":"string","maxLength":2000},"promptText":{"default":"","type":"string","maxLength":5000},"previewImageUrls":{"minItems":1,"type":"array","items":{"type":"string","format":"uri"}},"imageR2Keys":{"type":"array","items":{"type":"string"}},"tags":{"default":[],"maxItems":10,"type":"array","items":{"type":"string","minLength":1,"maxLength":50}}},"required":["title","description","promptText","previewImageUrls","tags"],"additionalProperties":false}}}},"responses":{"200":{"description":"Draft published","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"itemId":{"type":"string"},"message":{"type":"string"}},"required":["success","itemId","message"],"additionalProperties":false}}}},"400":{"description":"Validation or prohibited content","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"401":{"description":"Missing or invalid API key","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/auth/start":{"post":{"tags":["CLI Auth"],"summary":"Start a CLI login session","description":"Starts an OAuth-like device code flow. No authentication required. Returns a sessionId and a loginUrl to open in a browser.","responses":{"200":{"description":"Session started","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"sessionId":{"type":"string"},"loginUrl":{"type":"string","format":"uri"},"expiresAt":{"type":"number","description":"Unix ms when the session expires (10 minutes from issuance)"},"message":{"type":"string"}},"required":["success","sessionId","loginUrl","expiresAt","message"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/auth/approve":{"post":{"tags":["CLI Auth"],"summary":"Approve a CLI session (browser-only)","description":"Called by the browser approval page after the user signs in. Approves the session and generates a fresh API key. Requires a signed-in Clerk session; **not** the API key header.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"sessionId":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$"}},"required":["sessionId"],"additionalProperties":false}}}},"responses":{"200":{"description":"Session approved","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"}},"required":["success","message"],"additionalProperties":false}}}},"401":{"description":"Not signed in","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"410":{"description":"Session expired","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"422":{"description":"Too many API keys","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}},"/api/v1/auth/poll/{sessionId}":{"get":{"tags":["CLI Auth"],"summary":"Poll for an issued API key","description":"The CLI polls this endpoint until the user approves the session in their browser. On completion, returns the API key exactly once.","parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Pending or completed","content":{"application/json":{"schema":{"oneOf":[{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"status":{"type":"string","const":"pending"}},"required":["success","status"],"additionalProperties":false},{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":true},"status":{"type":"string","const":"completed"},"apiKey":{"type":"string"},"message":{"type":"string"}},"required":["success","status","apiKey","message"],"additionalProperties":false}]}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"409":{"description":"API key already retrieved","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"410":{"description":"Session expired","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"X-Api-Key","description":"API key starting with `ip2p_`. Obtain at https://kirigami.ai/settings/api-keys"}},"schemas":{"ErrorResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"success":{"type":"boolean","const":false},"error":{"type":"string","description":"Human-readable error message (localized)"},"code":{"type":"string","description":"Machine-readable error code"}},"required":["success","error","code"],"additionalProperties":false}}}}