{"openapi":"3.1.0","info":{"title":"Legacy File Converter public API","version":"1.0.0","summary":"Versioned public HTTP API (v1) for the Legacy File Converter website","description":"Public endpoints for live pricing, Windows installer download, roadmap voting, feedback intake, and Stripe Checkout session helpers used by the Legacy File Converter desktop app and website. Legacy File Converter is a Windows desktop product (Green 18 Enterprises). Conversion Library Plus includes local search, Photo Map for geotagged images, and EXIF place/date/camera text — those features run in the desktop app, not as separate HTTP APIs. ## Versioning and deprecation\nCanonical paths are `/api/v1/*`. Matching unversioned `/api/*` paths are stable aliases for the same v1 handlers and will not diverge without a new major version (`/api/v2/*`). Deprecations (if any) will be announced in this document and via HTTP `Deprecation` / `Sunset` headers with at least 90 days notice before removal. This specification documents only existing public routes. Admin (`/api/adm1n/*`) and Stripe webhook routes are intentionally omitted. There is no OAuth, GraphQL, MCP, or product CLI surface.","contact":{"name":"Legacy File Converter support","email":"support@legacyfileconverter.com","url":"https://legacyfileconverter.com/developers"},"license":{"name":"Proprietary","url":"https://legacyfileconverter.com/terms"}},"externalDocs":{"description":"Legacy File Converter developer resources (OpenAPI, llms.txt, markdown negotiation, when-to-use)","url":"https://legacyfileconverter.com/developers"},"servers":[{"url":"https://legacyfileconverter.com","description":"Production"}],"tags":[{"name":"Pricing","description":"Live license and trial pricing."},{"name":"Download","description":"Windows MSI installer download."},{"name":"Roadmap","description":"Public roadmap features and votes."},{"name":"Feedback","description":"Feedback and feature requests from the site and desktop app."},{"name":"Checkout","description":"Stripe Checkout session create/status for the desktop app."},{"name":"Analytics","description":"Lightweight first-party visit and Store-click beacons."}],"paths":{"/api/v1/pricing":{"get":{"operationId":"getLivePricing","tags":["Pricing"],"summary":"Get live pricing payload","description":"Returns current Standard, Plus, commercial, and trial limits used by the website and desktop purchase UI. No authentication. Alias: GET /api/pricing.","security":[],"parameters":[],"responses":{"200":{"description":"Live pricing payload","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PricingPayload"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Pricing unavailable","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/download":{"get":{"operationId":"downloadWindowsInstaller","tags":["Download"],"summary":"Download the Windows MSI installer","description":"Streams the current Legacy File Converter MSI. Non-Windows browser user agents are redirected to /download-help unless force=1. Automated clients (WinGet, curl, etc.) receive the installer bytes. Alias: GET /api/download.","security":[],"parameters":[{"name":"force","in":"query","required":false,"description":"Set to 1 to bypass the non-Windows browser redirect.","schema":{"type":"string","enum":["1"]}},{"name":"utm_source","in":"query","required":false,"schema":{"type":"string"}},{"name":"utm_medium","in":"query","required":false,"schema":{"type":"string"}},{"name":"utm_campaign","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Installer bytes (application/octet-stream)","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"302":{"description":"Redirect to /download-help for non-Windows browsers"},"404":{"description":"Installer unavailable","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Upstream installer fetch failed","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"head":{"operationId":"headWindowsInstaller","tags":["Download"],"summary":"Installer availability / size headers","description":"HEAD variant of the MSI download for WinGet and validators. Alias: HEAD /api/download.","security":[],"parameters":[],"responses":{"200":{"description":"Installer available","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}}},"404":{"description":"Installer unavailable","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Upstream HEAD failed","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/roadmap":{"get":{"operationId":"listRoadmapFeatures","tags":["Roadmap"],"summary":"List visible roadmap features","description":"Returns visible roadmap features and whether the caller IP has voted. Alias: GET /api/roadmap.","security":[],"parameters":[],"responses":{"200":{"description":"Roadmap feature list","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoadmapListResponse"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"post":{"operationId":"toggleRoadmapVote","tags":["Roadmap"],"summary":"Toggle a vote on a roadmap feature","description":"Adds or removes a vote for the caller IP on a visible feature. Alias: POST /api/roadmap.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["featureId"],"additionalProperties":false,"properties":{"featureId":{"type":"integer","minimum":1}}}}}},"responses":{"200":{"description":"Updated vote state","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoadmapVoteResponse"}}}},"400":{"description":"Invalid request","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Feature not found","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Server error","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/feedback":{"post":{"operationId":"submitFeedback","tags":["Feedback"],"summary":"Submit feedback or a feature request","description":"Public feedback intake used by the desktop app and the roadmap suggest-a-feature form. Reviews may include a 1–5 rating. Alias: POST /api/feedback.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackRequest"}}}},"responses":{"201":{"description":"Accepted","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"type":"object","required":["success"],"additionalProperties":false,"properties":{"success":{"type":"boolean","const":true}}}}}},"400":{"description":"Validation error","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Server error","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/checkout/create":{"post":{"operationId":"createCheckoutSession","tags":["Checkout"],"summary":"Create a Stripe Checkout session","description":"Creates a Stripe Checkout session for Standard, Plus add-on, or Standard+Plus bundle. Used by the desktop in-app purchase flow. Alias: POST /api/checkout/create.","security":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutCreateRequest"}}}},"responses":{"200":{"description":"Checkout session created","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutCreateResponse"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Checkout creation failed","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/checkout/status":{"get":{"operationId":"getCheckoutStatus","tags":["Checkout"],"summary":"Read checkout / license fulfillment status","description":"Returns pending, processing, or paid status for a Stripe Checkout session, including license keys when fulfillment has completed. Alias: GET /api/checkout/status.","security":[],"parameters":[{"name":"session_id","in":"query","required":true,"description":"Stripe Checkout session id","schema":{"type":"string","minLength":1}}],"responses":{"200":{"description":"Status payload","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutStatusResponse"}}}},"400":{"description":"Missing session_id","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"500":{"description":"Lookup failed","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/track":{"post":{"operationId":"trackPageVisit","tags":["Analytics"],"summary":"Record a page visit beacon","description":"First-party analytics beacon used by site middleware. Returns 204. Alias: POST /api/track.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["path"],"additionalProperties":false,"properties":{"path":{"type":"string"},"referer":{"type":"string"},"userAgent":{"type":"string"},"ip":{"type":"string"}}}}}},"responses":{"204":{"description":"Recorded (or ignored)","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/api/v1/store-install-click":{"post":{"operationId":"trackMicrosoftStoreInstallClick","tags":["Analytics"],"summary":"Record a Microsoft Store install click","description":"Records a Store badge / install click in download_events. Returns 204. Alias: POST /api/store-install-click.","security":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"referer":{"type":"string"},"userAgent":{"type":"string"},"ip":{"type":"string"}}}}}},"responses":{"204":{"description":"Recorded (or ignored)","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45}}},"429":{"description":"Rate limited","headers":{"RateLimit-Policy":{"description":"IETF RateLimit-Policy structured field. Default: \"public-api\";q=120;w=60","schema":{"type":"string"},"example":"\"public-api\";q=120;w=60"},"RateLimit":{"description":"IETF RateLimit structured field with remaining quota (r) and seconds until reset (t).","schema":{"type":"string"},"example":"\"public-api\";r=119;t=45"},"RateLimit-Limit":{"description":"Compatibility form of the request quota for the current window.","schema":{"type":"integer"},"example":120},"RateLimit-Remaining":{"description":"Compatibility form of remaining requests in the current window.","schema":{"type":"integer"},"example":119},"RateLimit-Reset":{"description":"Compatibility form: seconds until the current window resets.","schema":{"type":"integer"},"example":45},"Retry-After":{"description":"Seconds to wait before retrying (present on 429).","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}}},"components":{"schemas":{"ApiError":{"type":"object","title":"ApiError","required":["code","message","resolution"],"additionalProperties":false,"properties":{"code":{"type":"string","description":"Stable machine-readable error code (e.g. not_found, rate_limited).","examples":["not_found","rate_limited","invalid_json"]},"message":{"type":"string","description":"Human-readable error summary."},"resolution":{"type":"string","description":"What an agent or client should do next to recover."}}},"PricingPayload":{"type":"object","required":["product","productDisplayName","currency","licensePrice","licensePriceDisplay","trialFileLimit"],"additionalProperties":false,"properties":{"product":{"type":"string","const":"legacy"},"productDisplayName":{"type":"string"},"currency":{"type":"string","const":"USD"},"licensePrice":{"type":"string"},"licensePriceDisplay":{"type":"string"},"stripePaymentLink":{"type":"string","format":"uri"},"commercialLicensePrice":{"type":"string"},"commercialLicensePriceDisplay":{"type":"string"},"stripeCommercialPaymentLink":{"type":"string","format":"uri"},"trialFileLimit":{"type":"integer"},"plusAddonPrice":{"type":"string"},"plusAddonPriceDisplay":{"type":"string"},"stripePlusAddonPaymentLink":{"type":"string","format":"uri"},"plusBundlePrice":{"type":"string"},"plusBundlePriceDisplay":{"type":"string"},"stripePlusBundlePaymentLink":{"type":"string","format":"uri"},"plusCommercialPrice":{"type":"string"},"plusCommercialPriceDisplay":{"type":"string"},"stripePlusCommercialPaymentLink":{"type":"string","format":"uri"},"plusAddonCommercialPrice":{"type":"string"},"plusAddonCommercialPriceDisplay":{"type":"string"},"stripePlusAddonCommercialPaymentLink":{"type":"string","format":"uri"}}},"RoadmapFeature":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"integer"},"title":{"type":"string"},"description":{"type":"string"},"category":{"type":"string"},"vote_count":{"type":"integer"},"voted":{"type":"boolean"},"release_version":{"type":["string","null"]}}},"RoadmapListResponse":{"type":"object","required":["features"],"additionalProperties":false,"properties":{"features":{"type":"array","items":{"$ref":"#/components/schemas/RoadmapFeature"}}}},"RoadmapVoteResponse":{"type":"object","required":["voted","vote_count"],"additionalProperties":false,"properties":{"voted":{"type":"boolean"},"vote_count":{"type":"integer"}}},"FeedbackRequest":{"type":"object","required":["description"],"additionalProperties":false,"properties":{"type":{"type":"string","enum":["feature_request","bug_report","general","review"]},"email":{"type":"string","format":"email"},"description":{"type":"string","minLength":1},"appVersion":{"type":"string"},"rating":{"type":"integer","minimum":1,"maximum":5}}},"CheckoutCreateRequest":{"type":"object","additionalProperties":false,"properties":{"channel":{"type":"string","enum":["store","msi"]},"product":{"type":"string","enum":["standard","plus_addon","plus_bundle","plus","bundle","addon"],"description":"License product. Defaults to standard."}}},"CheckoutCreateResponse":{"type":"object","required":["sessionId","url"],"additionalProperties":false,"properties":{"sessionId":{"type":"string"},"url":{"type":"string","format":"uri"}}},"CheckoutStatusResponse":{"oneOf":[{"type":"object","required":["status"],"additionalProperties":false,"properties":{"status":{"type":"string","enum":["pending","processing"]}}},{"type":"object","required":["status","licenseKey"],"additionalProperties":false,"properties":{"status":{"type":"string","const":"paid"},"licenseKey":{"type":["string","null"]},"standardLicenseKey":{"type":["string","null"]},"plusLicenseKey":{"type":["string","null"]}}}]}}}}