{"components":{"schemas":{"CanvasElement":{"properties":{"height":{"description":"% of product width","type":"number"},"position":{"properties":{"x":{"description":"% of product width","type":"number"},"y":{"description":"% of product height","type":"number"}},"type":"object"},"type":{"enum":["text","shape","image","qr","pattern"],"type":"string"},"width":{"description":"% of product width","type":"number"}},"type":"object"},"Design":{"properties":{"created_at":{"format":"date-time","type":"string"},"elements":{"items":{"$ref":"#/components/schemas/CanvasElement"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"product_id":{"type":"string"},"updated_at":{"format":"date-time","type":"string"}},"type":"object"},"FormField":{"properties":{"id":{"type":"string"},"label":{"type":"string"},"order":{"type":"integer"},"placeholder":{"type":"string"},"required":{"type":"boolean"},"type":{"enum":["text","email","tel","textarea","select","number","image"],"type":"string"}},"type":"object"},"Geometry":{"properties":{"active":{"type":"boolean"},"height_mm":{"type":"number"},"id":{"type":"string"},"name":{"type":"string"},"safe_margin_mm":{"type":"number"},"shape_type":{"type":"string"},"svg_data":{"description":"SVG path d attribute","type":"string"},"svg_viewbox":{"type":"string"},"width_mm":{"type":"number"}},"type":"object"},"Material":{"properties":{"active":{"type":"boolean"},"category":{"type":"string"},"color_hex":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"texture_url":{"format":"uri","type":"string"}},"type":"object"},"Product":{"properties":{"configurator_enabled":{"type":"boolean"},"featured_image_url":{"format":"uri","type":"string"},"handle":{"type":"string"},"price":{"type":"string"},"shopify_product_id":{"type":"integer"},"title":{"type":"string"}},"type":"object"},"ProductConfig":{"properties":{"enabled_tools":{"items":{"type":"string"},"type":"array"},"geometry":{"properties":{"diameter_mm":{"type":"number"},"height_mm":{"type":"number"},"type":{"enum":["circle","rectangle","portrait","custom_svg"],"type":"string"},"width_mm":{"type":"number"}},"type":"object"},"image_url":{"format":"uri","type":"string"},"interaction_mode":{"enum":["engraving","print"],"type":"string"},"materials":{"items":{"$ref":"#/components/schemas/Material"},"type":"array"},"production_mode":{"type":"string"},"title":{"type":"string"}},"type":"object"},"Template":{"properties":{"category":{"type":"string"},"compatible_methods":{"items":{"type":"string"},"type":"array"},"description":{"type":"string"},"elements":{"items":{"$ref":"#/components/schemas/CanvasElement"},"type":"array"},"form_fields":{"items":{"$ref":"#/components/schemas/FormField"},"type":"array"},"id":{"type":"string"},"name":{"type":"string"},"preview_image_url":{"format":"uri","type":"string"},"rating_average":{"type":"number"},"type":{"enum":["form","inspiration"],"type":"string"},"usage_count":{"type":"integer"}},"type":"object"}},"securitySchemes":{"ApiKeyAuth":{"description":"Etchify API key (sk_etch_...). Generate in Settings \u2192 AI Integration. Scoped to one shop.","in":"header","name":"X-API-Key","type":"apiKey"},"BearerAuth":{"bearerFormat":"JWT","description":"Shopify Session Token (from App Bridge) or Supabase Access Token. Pass as 'Authorization: Bearer <token>'.","scheme":"bearer","type":"http"},"ShopQuery":{"description":"Shopify store domain (e.g. mystore.myshopify.com). Required for all public endpoints.","in":"query","name":"shop","type":"apiKey"}}},"info":{"contact":{"email":"help@etchify.app","name":"Etchify Support","url":"https://etchify.app"},"description":"REST API for Etchify \u2014 Shopify Engraving & Print Configurator. Manage products, templates, materials, shapes, and customer designs.","title":"Etchify API","version":"1.0.0"},"openapi":"3.0.3","paths":{"/api/admin/shop-settings":{"get":{"operationId":"getShopSettings","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"settings":{"properties":{"backside_enabled":{"type":"boolean"},"backside_label":{"type":"string"},"backside_price_multiplier":{"type":"number"},"default_production_mode":{"type":"string"},"series_default_type":{"type":"string"},"series_enabled":{"type":"boolean"}},"type":"object"}},"type":"object"}}},"description":"Shop settings including production mode, series config, backside settings"}},"security":[{"BearerAuth":[]}],"summary":"Get shop-level settings","tags":["Settings"]},"post":{"operationId":"saveShopSettings","requestBody":{"content":{"application/json":{"schema":{"type":"object"}}},"required":true},"responses":{"200":{"description":"Settings saved"}},"security":[{"BearerAuth":[]}],"summary":"Update shop-level settings","tags":["Settings"]}},"/api/branding/all":{"get":{"operationId":"getBranding","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"colors":{"properties":{"primary":{"type":"string"},"secondary":{"type":"string"}},"type":"object"},"features":{"properties":{"backside_engraving":{"type":"boolean"},"customer_accounts":{"type":"boolean"},"draft_orders":{"type":"boolean"},"qr_codes":{"type":"boolean"}},"type":"object"},"has_custom_logo":{"type":"boolean"},"logo_url":{"format":"uri","type":"string"}},"type":"object"}}},"description":"Branding configuration"}},"security":[{"BearerAuth":[]}],"summary":"Get shop branding (logo, colors, features)","tags":["Settings"]}},"/api/designs":{"get":{"operationId":"listDesigns","parameters":[{"in":"query","name":"shop","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"designs":{"items":{"$ref":"#/components/schemas/Design"},"type":"array"}},"type":"object"}}},"description":"List of saved designs"}},"summary":"List saved customer designs","tags":["Designs"]}},"/api/geometries/admin/list":{"get":{"operationId":"listShapes","parameters":[{"in":"query","name":"shop","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"geometries":{"items":{"$ref":"#/components/schemas/Geometry"},"type":"array"}},"type":"object"}}},"description":"Shape library"}},"security":[{"BearerAuth":[]}],"summary":"List all shapes/geometries in the library (admin, requires auth)","tags":["Shapes"]}},"/api/materials/admin/list":{"get":{"operationId":"listMaterials","parameters":[{"in":"query","name":"shop","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"materials":{"items":{"$ref":"#/components/schemas/Material"},"type":"array"}},"type":"object"}}},"description":"Material library"}},"security":[{"BearerAuth":[]}],"summary":"List all materials in the library (admin, requires auth)","tags":["Materials"]}},"/api/openapi.json":{"get":{"operationId":"getOpenApiSpec","responses":{"200":{"description":"OpenAPI 3.0 specification document"}},"summary":"Get this OpenAPI specification","tags":["System"]}},"/api/products/config/{product_id}":{"get":{"description":"Returns interaction mode, production mode, enabled tools, geometry, materials, and dimensions. Accepts numeric Shopify product ID, configurator_product_id, or Shopify handle.","operationId":"getProductConfig","parameters":[{"description":"Product identifier (numeric ID, handle, or configurator_product_id)","in":"path","name":"product_id","required":true,"schema":{"type":"string"}},{"in":"query","name":"shop","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductConfig"}}},"description":"Product configuration"}},"summary":"Get product configuration for the configurator","tags":["Products"]}},"/api/products/configurator":{"get":{"description":"Returns all products that the shop owner has activated for the Etchify configurator. Use format=simple for a compact response.","operationId":"getConfiguratorProducts","parameters":[{"description":"Shopify store domain (e.g. mystore.myshopify.com)","in":"query","name":"shop","required":true,"schema":{"type":"string"}},{"description":"Response format \u2014 simple returns essential fields only","in":"query","name":"format","schema":{"default":"simple","enum":["simple","full"],"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Product"},"type":"array"}}},"description":"List of configurator-enabled products"}},"summary":"List products enabled for the configurator (public, no auth needed)","tags":["Products"]}},"/api/templates/admin":{"get":{"operationId":"listTemplatesAdmin","parameters":[{"in":"query","name":"search","schema":{"type":"string"}},{"in":"query","name":"category","schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"count":{"type":"integer"},"templates":{"items":{"$ref":"#/components/schemas/Template"},"type":"array"}},"type":"object"}}},"description":"All templates for this shop"}},"security":[{"BearerAuth":[]}],"summary":"List all templates (admin view, includes inactive)","tags":["Templates"]},"post":{"operationId":"createTemplate","requestBody":{"content":{"application/json":{"schema":{"properties":{"description":{"type":"string"},"elements":{"items":{"$ref":"#/components/schemas/CanvasElement"},"type":"array"},"formFields":{"items":{"$ref":"#/components/schemas/FormField"},"type":"array"},"name":{"type":"string"},"productIds":{"items":{"type":"string"},"type":"array"},"tags":{"items":{"type":"string"},"type":"array"},"template_type":{"enum":["form","inspiration"],"type":"string"}},"required":["name"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Template created"}},"security":[{"BearerAuth":[]}],"summary":"Create a new template","tags":["Templates"]}},"/api/templates/gallery":{"get":{"description":"Returns templates filtered by shop, product, manufacturing method, and category. Sorted by curated > rating > usage.","operationId":"getTemplateGallery","parameters":[{"in":"query","name":"shop","required":true,"schema":{"type":"string"}},{"description":"Filter by Shopify product ID","in":"query","name":"product","schema":{"type":"string"}},{"in":"query","name":"method","schema":{"enum":["laser_engraving","printing","cnc_milling","cutting"],"type":"string"}},{"in":"query","name":"category","schema":{"type":"string"}},{"description":"form = fixed layout, inspiration = free editing","in":"query","name":"template_type","schema":{"enum":["form","inspiration"],"type":"string"}},{"in":"query","name":"limit","schema":{"default":20,"type":"integer"}},{"in":"query","name":"offset","schema":{"default":0,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"categories":{"items":{"type":"string"},"type":"array"},"templates":{"items":{"$ref":"#/components/schemas/Template"},"type":"array"},"total":{"type":"integer"}},"type":"object"}}},"description":"Template gallery results"}},"summary":"Browse template gallery","tags":["Templates"]}},"/api/templates/gallery/{template_id}/apply":{"post":{"operationId":"applyTemplate","parameters":[{"in":"path","name":"template_id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"form_data":{"description":"Key-value map of form field IDs to user values","type":"object"}},"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"elements":{"properties":{"back":{"items":{"$ref":"#/components/schemas/CanvasElement"},"type":"array"},"front":{"items":{"$ref":"#/components/schemas/CanvasElement"},"type":"array"}},"type":"object"}},"type":"object"}}},"description":"Rendered template elements"}},"summary":"Apply a template with custom form values","tags":["Templates"]}},"/api/v1/me":{"get":{"operationId":"getMe","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"shop_domain":{"example":"mystore.myshopify.com","type":"string"}},"type":"object"}}},"description":"Shop domain associated with the API key"}},"security":[{"ApiKeyAuth":[]}],"summary":"Get shop domain for this API key","tags":["System"]}},"/health":{"get":{"operationId":"healthCheck","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"status":{"example":"ok","type":"string"}},"type":"object"}}},"description":"Service is healthy"}},"summary":"Health check endpoint","tags":["System"]}}},"servers":[{"description":"Production","url":"https://api.etchify.app"},{"description":"Staging","url":"https://api-dev.etchify.app"}]}
