{"components":{"schemas":{"ClaimBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/ClaimBody.json"],"format":"uri","readOnly":true,"type":"string"},"vendor":{"description":"Vendor slug to attribute the change to (dev only; ignored when the GitHub bot is configured).","type":"string"}},"type":"object"},"ClaimOutputBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/ClaimOutputBody.json"],"format":"uri","readOnly":true,"type":"string"},"alreadyExisted":{"description":"True when an idempotent retry returned an existing pull request.","type":"boolean"},"branch":{"description":"Head branch the change was committed to.","type":"string"},"claimed":{"description":"Always true on success.","type":"boolean"},"files":{"description":"Repository paths the presets were placed at.","items":{"type":"string"},"type":["array","null"]},"message":{"description":"Human-readable note, e.g. when no pull request was opened.","type":"string"},"prCreated":{"description":"Whether a pull request was opened (false in dev without the bot).","type":"boolean"},"pullRequestUrl":{"description":"URL of the opened pull request, when one was created.","type":"string"},"vendor":{"description":"Vendor slug the change was attributed to.","type":"string"}},"required":["claimed","prCreated","vendor","files"],"type":"object"},"DraftFileView":{"additionalProperties":false,"properties":{"content":{"description":"The original, unmodified uploaded YAML.","type":"string"},"fileName":{"description":"Leaf file name the preset is stored as (\u003cid\u003e.yaml).","type":"string"},"id":{"description":"Preset id declared in the file body.","type":"string"},"kind":{"description":"Preset category: printer, filament, or process.","type":"string"},"name":{"description":"Human-readable preset name.","type":"string"},"vendor":{"description":"Vendor string declared in the body, when applicable.","type":"string"}},"required":["kind","id","name","fileName","content"],"type":"object"},"ErrorDetail":{"additionalProperties":false,"properties":{"location":{"description":"Where the error occurred, e.g. 'body.items[3].tags' or 'path.thing-id'","type":"string"},"message":{"description":"Error message text","type":"string"},"value":{"description":"The value at the given location"}},"type":"object"},"ErrorModel":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/ErrorModel.json"],"format":"uri","readOnly":true,"type":"string"},"detail":{"description":"A human-readable explanation specific to this occurrence of the problem.","examples":["Property foo is required but is missing."],"type":"string"},"errors":{"description":"Optional list of individual error details","items":{"$ref":"#/components/schemas/ErrorDetail"},"type":["array","null"]},"instance":{"description":"A URI reference that identifies the specific occurrence of the problem.","examples":["https://example.com/error-log/abc123"],"format":"uri","type":"string"},"status":{"description":"HTTP status code","examples":[400],"format":"int64","type":"integer"},"title":{"description":"A short, human-readable summary of the problem type. This value should not change between occurrences of the error.","examples":["Bad Request"],"type":"string"},"type":{"default":"about:blank","description":"A URI reference to human-readable documentation for the error.","examples":["https://example.com/errors/example"],"format":"uri","type":"string"}},"type":"object"},"GetUploadOutputBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/GetUploadOutputBody.json"],"format":"uri","readOnly":true,"type":"string"},"createdAt":{"format":"date-time","type":"string"},"expiresAt":{"format":"date-time","type":"string"},"files":{"items":{"$ref":"#/components/schemas/DraftFileView"},"type":["array","null"]},"id":{"type":"string"}},"required":["id","createdAt","expiresAt","files"],"type":"object"},"HealthResponseBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/HealthResponseBody.json"],"format":"uri","readOnly":true,"type":"string"},"lastIngestAt":{"description":"Time of the last successful ingest, or null until the first ingest.","format":"date-time","type":["string","null"]},"ready":{"description":"True once a catalog has been loaded. False until the first successful ingest.","type":"boolean"},"revision":{"description":"Git commit SHA of the served catalog, or null until the first ingest.","type":["string","null"]},"status":{"description":"Liveness marker; always \"ok\" when the process can respond.","examples":["ok"],"type":"string"}},"required":["status","ready","revision","lastIngestAt"],"type":"object"},"ListVendorsResponseBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/ListVendorsResponseBody.json"],"format":"uri","readOnly":true,"type":"string"},"next_cursor":{"description":"Continuation token; absent on the last page.","type":"string"},"revision":{"description":"Catalog revision the page was served from.","type":"string"},"vendors":{"description":"The page of vendor directory entries.","items":{"$ref":"#/components/schemas/Vendor"},"type":["array","null"]}},"required":["vendors","revision"],"type":"object"},"MatchInfo":{"additionalProperties":false,"properties":{"field":{"description":"Name of the field the query matched.","type":"string"},"ranges":{"description":"Offsets within the field value that matched.","items":{"items":{"format":"int64","type":"integer"},"maxItems":2,"minItems":2,"type":["array","null"]},"type":["array","null"]}},"required":["field","ranges"],"type":"object"},"PresetResponseBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/PresetResponseBody.json"],"format":"uri","readOnly":true,"type":"string"},"id":{"description":"Stable identifier of the preset.","type":"string"},"import_url":{"description":"Canonical URL of this preset, for re-import into the slicer.","format":"uri","type":"string"},"name":{"description":"Human-readable preset name.","type":"string"},"params":{"additionalProperties":{},"description":"The preset's slicing parameters in the slicer's own field names and units.","type":"object"},"source":{"description":"Where the preset came from; always \"catalog\" when served here.","enum":["catalog"],"type":"string"},"type":{"description":"Kind of profile the preset describes.","enum":["printer","filament","process"],"type":"string"},"vendor":{"description":"Vendor slug the preset belongs to.","type":"string"}},"required":["id","type","name","vendor","source","import_url","params"],"type":"object"},"PresetSummary":{"additionalProperties":false,"properties":{"id":{"description":"Stable identifier of the preset.","type":"string"},"match":{"$ref":"#/components/schemas/MatchInfo","description":"Where the query matched, for highlighting."},"material":{"description":"Filament material, when applicable.","type":"string"},"model":{"description":"Printer model, when applicable.","type":"string"},"name":{"description":"Human-readable preset name.","type":"string"},"spec":{"description":"Short human-readable spec string.","type":"string"},"type":{"description":"Kind of profile the preset describes.","enum":["printer","filament","process"],"type":"string"},"vendor":{"description":"Vendor slug the preset belongs to.","type":"string"}},"required":["id","type","name","vendor","spec"],"type":"object"},"SearchResponseBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/SearchResponseBody.json"],"format":"uri","readOnly":true,"type":"string"},"next_cursor":{"description":"Continuation token; absent on the last page.","type":"string"},"results":{"description":"The page of matching preset summaries.","items":{"$ref":"#/components/schemas/PresetSummary"},"type":["array","null"]},"revision":{"description":"Catalog revision the page was served from.","type":"string"}},"required":["results","revision"],"type":"object"},"UploadOutputBody":{"additionalProperties":false,"properties":{"$schema":{"description":"A URL to the JSON Schema for this object.","examples":["https://example.com/v1/schemas/UploadOutputBody.json"],"format":"uri","readOnly":true,"type":"string"},"claimUrl":{"description":"Admin app path to review and claim the draft.","type":"string"},"expiresAt":{"description":"When the draft is garbage-collected if unclaimed.","format":"date-time","type":"string"},"files":{"description":"The validated preset files in the draft.","items":{"$ref":"#/components/schemas/DraftFileView"},"type":["array","null"]},"id":{"description":"Unguessable id of the parked draft.","type":"string"}},"required":["id","claimUrl","expiresAt","files"],"type":"object"},"Vendor":{"additionalProperties":false,"properties":{"display_name":{"description":"Human-readable vendor name.","type":"string"},"slug":{"description":"Stable vendor slug, matching the vendor.yaml directory name.","type":"string"},"website":{"description":"Vendor website, when the manifest declares one.","format":"uri","type":"string"}},"required":["slug","display_name"],"type":"object"}}},"info":{"description":"In-memory, searchable catalog of 3D printer presets served from ColdCrabby/presets. See docs/api-surface.md.","title":"Cold Crabby Preset Cloud","version":"1.0.0"},"openapi":"3.1.0","paths":{"/v1/health":{"get":{"description":"Reports process liveness, catalog readiness, the served catalog revision, and the time of the last successful ingest.","operationId":"getHealth","responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponseBody"}}},"description":"OK"},"default":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Error"}},"summary":"Liveness and readiness","tags":["Operations"]}},"/v1/presets":{"get":{"description":"Searches the in-memory catalog of presets ingested from ColdCrabby/presets. Returns a page of summaries for rendering result rows.","operationId":"searchPresets","parameters":[{"description":"Fuzzy query across name, vendor, model, material. Omit to browse.","explode":false,"in":"query","name":"q","schema":{"description":"Fuzzy query across name, vendor, model, material. Omit to browse.","type":"string"}},{"description":"Restrict to one preset type.","explode":false,"in":"query","name":"type","schema":{"description":"Restrict to one preset type.","enum":["printer","filament","process"],"type":"string"}},{"description":"Restrict to one vendor slug.","explode":false,"in":"query","name":"vendor","schema":{"description":"Restrict to one vendor slug.","type":"string"}},{"description":"Restrict to one filament material.","explode":false,"in":"query","name":"material","schema":{"description":"Restrict to one filament material.","type":"string"}},{"description":"Maximum results to return (bounded server-side).","explode":false,"in":"query","name":"limit","schema":{"description":"Maximum results to return (bounded server-side).","format":"int64","maximum":100,"minimum":1,"type":"integer"}},{"description":"Opaque continuation token from a previous page.","explode":false,"in":"query","name":"cursor","schema":{"description":"Opaque continuation token from a previous page.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponseBody"}}},"description":"OK"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Unprocessable Entity"},"500":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Internal Server Error"},"503":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Service Unavailable"}},"summary":"Search or browse the preset catalog","tags":["public"]}},"/v1/presets/{id}":{"get":{"description":"Returns the complete preset identified by id, with source \"catalog\" and a canonical import_url. This is the exact JSON the slicer can consume directly, so a client imports one preset without downloading the whole catalog.","operationId":"getPreset","parameters":[{"description":"Stable identifier of the preset to fetch.","in":"path","name":"id","required":true,"schema":{"description":"Stable identifier of the preset to fetch.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresetResponseBody"}}},"description":"OK"},"404":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Not Found"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Unprocessable Entity"},"500":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Internal Server Error"},"503":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Service Unavailable"}},"summary":"Fetch a complete preset in the slicer's profile shape","tags":["public"]}},"/v1/uploads":{"post":{"description":"Accepts preset YAML files, or a .zip laid out like the presets repository, validates each against the pinned schemas, and parks the result as a short-lived draft. Returns the draft id and the admin URL to claim it.","operationId":"uploadPresets","parameters":[{"description":"Default preset type for bare files whose name does not encode one (printers/ or filaments/). Ignored for zip entries, whose kind comes from their path.","explode":false,"in":"query","name":"type","schema":{"description":"Default preset type for bare files whose name does not encode one (printers/ or filaments/). Ignored for zip entries, whose kind comes from their path.","enum":["printer","filament"],"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"encoding":{"files":{"contentType":"application/octet-stream"}},"schema":{"properties":{"files":{"items":{"contentEncoding":"binary","contentMediaType":"application/octet-stream","format":"binary","type":"string"},"type":"array"}},"required":["files"],"type":"object"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOutputBody"}}},"description":"Created"},"default":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Error"}},"summary":"Upload presets to park for claiming","tags":["Uploads"]}},"/v1/uploads/{id}":{"get":{"description":"Returns a parked upload draft so the admin app can render it for review. The id is the only capability required; ownership is checked at claim time.","operationId":"getUpload","parameters":[{"description":"Draft id returned by POST /v1/uploads.","in":"path","name":"id","required":true,"schema":{"description":"Draft id returned by POST /v1/uploads.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetUploadOutputBody"}}},"description":"OK"},"default":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Error"}},"summary":"Read a parked upload","tags":["Uploads"]}},"/v1/uploads/{id}/claim":{"post":{"description":"Authorizes the caller's organization against the vendor manifest at the current head, re-validates the draft, and opens a pull request through the bot. Requires a Stytch session JWT.","operationId":"claimUpload","parameters":[{"description":"Draft id to claim.","in":"path","name":"id","required":true,"schema":{"description":"Draft id to claim.","type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimBody"}}}},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimOutputBody"}}},"description":"OK"},"default":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Error"}},"summary":"Claim an upload and open a pull request","tags":["Uploads"]}},"/v1/vendors":{"get":{"description":"Returns a page of the vendor directory derived from the vendor.yaml manifests in the served catalog. The directory is cursor-paginated so it is never dumped in one response; the stytch_organization_id is not part of the public representation.","operationId":"listVendors","parameters":[{"description":"Maximum vendors to return (bounded server-side).","explode":false,"in":"query","name":"limit","schema":{"description":"Maximum vendors to return (bounded server-side).","format":"int64","maximum":100,"minimum":1,"type":"integer"}},{"description":"Opaque continuation token from a previous page.","explode":false,"in":"query","name":"cursor","schema":{"description":"Opaque continuation token from a previous page.","type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListVendorsResponseBody"}}},"description":"OK"},"409":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Conflict"},"422":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Unprocessable Entity"},"500":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Internal Server Error"},"503":{"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ErrorModel"}}},"description":"Service Unavailable"}},"summary":"List the vendor directory","tags":["Vendors"]}}}}