{"openapi":"3.1.0","info":{"title":"Gifcraft API","version":"0.1.0","description":"A fully local, hand-curated GIF/WebP/APNG/video format reference (frame-rate, palette-size and loop-count tradeoffs, file-size optimization, a when-to-use decision guide, GIF89a technical limits) plus a computed rough file-size estimator and a loop-count explainer.\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://gifcraft.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"hr@unifydynamics.com","url":"https://connectorbay.com/gifcraft/docs"},"termsOfService":"https://connectorbay.com/gifcraft/terms"},"servers":[{"url":"https://gifcraft.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/gifcraft/docs"},"security":[{},{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/format_info":{"post":{"operationId":"format_info","summary":"Full detail for one animated-image/video format: color depth, transparency, compression, audio support,","description":"Full detail for one animated-image/video format: color depth, transparency, compression, audio support,\n    animation mechanism, max dimensions, platform support. Use for \"tell me about animated WebP\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"format":{"description":"gif | webp_animated | apng | video","minLength":1,"title":"Format","type":"string"}},"required":["format"],"title":"format_infoArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/format_comparison":{"post":{"operationId":"format_comparison","summary":"Side-by-side comparison of named formats across color depth, transparency, compression, audio, and","description":"Side-by-side comparison of named formats across color depth, transparency, compression, audio, and\n    support. Use for \"compare GIF and WebP\", \"GIF vs APNG vs video\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"formats":{"description":"Two or more format names to compare.","items":{"type":"string"},"minItems":2,"title":"Formats","type":"array"}},"required":["formats"],"title":"format_comparisonArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/when_to_use":{"post":{"operationId":"when_to_use","summary":"Decision guide: recommends a format for a stated need (audio, smallest file size, widest compatibility,","description":"Decision guide: recommends a format for a stated need (audio, smallest file size, widest compatibility,\n    transparency with smooth gradients, broadcast/high-motion quality) with a reason. Use for \"GIF vs WebP vs\n    video, which should I use for a sticker\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"need":{"description":"A stated need, in plain language.","examples":["need audio","smallest file size for messaging","widest compatibility as a sticker"],"minLength":1,"title":"Need","type":"string"}},"required":["need"],"title":"when_to_useArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/frame_rate_tips":{"post":{"operationId":"frame_rate_tips","summary":"Frame-rate tradeoffs: GIF's centisecond delay granularity, a well-documented renderer quirk with very fast","description":"Frame-rate tradeoffs: GIF's centisecond delay granularity, a well-documented renderer quirk with very fast\n    delays, and the file-size effect of dropping frame rate. Use for \"why does my fast GIF look slower than I set\n    it\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"frame_rate_tipsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/palette_size_tips":{"post":{"operationId":"palette_size_tips","summary":"Palette-size tradeoffs: GIF's 256-color-per-frame cap, dithering vs banding, adaptive vs fixed palettes.","description":"Palette-size tradeoffs: GIF's 256-color-per-frame cap, dithering vs banding, adaptive vs fixed palettes.\n    Use for \"why does my GIF have visible color bands\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"palette_size_tipsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/file_size_optimization_tips":{"post":{"operationId":"file_size_optimization_tips","summary":"Concrete tips for reducing animated-image file size: frame count, cropping to changed regions, palette","description":"Concrete tips for reducing animated-image file size: frame count, cropping to changed regions, palette\n    size, dimensions, trimming dead time, and considering a different format entirely. Use for \"how do I make my\n    GIF file smaller\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"file_size_optimization_tipsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/gif_technical_limits":{"post":{"operationId":"gif_technical_limits","summary":"GIF89a's real specification limits: max colors per frame, transparency model, compression, frame-delay","description":"GIF89a's real specification limits: max colors per frame, transparency model, compression, frame-delay\n    unit, max canvas size, and the four disposal methods. Use for \"what's GIF's actual color limit\", \"what's a\n    disposal method in GIF\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"gif_technical_limitsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/loop_count_explainer":{"post":{"operationId":"loop_count_explainer","summary":"Explains GIF's NETSCAPE2.0 loop-count extension: 0 means infinite looping; a nonzero N means the animation","description":"Explains GIF's NETSCAPE2.0 loop-count extension: 0 means infinite looping; a nonzero N means the animation\n    plays once then repeats N more times. Give a specific loop_value to see what that exact value means in\n    playback. Use for \"what does GIF loop count 0 mean\", \"if I set loop count to 3, how many times does it play\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"loop_value":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":null,"description":"A specific loop-count value to explain; omit for the general explanation.","title":"Loop Value"}},"title":"loop_count_explainerArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/estimate_gif_size":{"post":{"operationId":"estimate_gif_size","summary":"Computed rough file-size estimate for a GIF, from canvas size, frame rate, duration, palette size and a","description":"Computed rough file-size estimate for a GIF, from canvas size, frame rate, duration, palette size and a\n    motion-level tier, using an explicitly labeled heuristic compression ratio per tier (real LZW compression is\n    highly content-dependent). Use for \"roughly how big will a 5 second 480x270 GIF at 15fps be\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"width":{"description":"Canvas width in pixels.","examples":[480],"exclusiveMinimum":0,"maximum":20000,"title":"Width","type":"integer"},"height":{"description":"Canvas height in pixels.","examples":[270],"exclusiveMinimum":0,"maximum":20000,"title":"Height","type":"integer"},"fps":{"description":"Frames per second.","examples":[15],"exclusiveMinimum":0,"maximum":100,"title":"Fps","type":"number"},"duration_seconds":{"description":"Duration in seconds.","examples":[5],"exclusiveMinimum":0,"maximum":3600,"title":"Duration Seconds","type":"number"},"palette_colors":{"default":256,"description":"Palette size (max 256 for GIF).","maximum":256,"minimum":2,"title":"Palette Colors","type":"integer"},"motion_level":{"default":"medium","description":"low | medium | high — how much the image changes frame to frame.","title":"Motion Level","type":"string"}},"required":["width","height","fps","duration_seconds"],"title":"estimate_gif_sizeArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/gif_glossary":{"post":{"operationId":"gif_glossary","summary":"Defines format terms: LZW, disposal method, indexed color, dithering, interlacing, frame delay, palette,","description":"Defines format terms: LZW, disposal method, indexed color, dithering, interlacing, frame delay, palette,\n    loop count, transparency index, alpha channel. Use for \"what's LZW\", \"what's an alpha channel\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"term":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"A specific term to look up; omit to list all.","title":"Term"}},"title":"gif_glossaryArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}