{"name":"Shop API","version":"1.0.0","description":"REST API for shop operations","endpoints":[{"method":"GET","path":"/api","description":"API documentation (this page)","authentication":"None"},{"method":"GET","path":"/api/check/:code","description":"Public pickup note page for an Abholung QR code (from JTL tAbholQR)","authentication":"None","parameters":{"code":"QR code token (cCode)"},"response":"HTML page with the customer pickup note"},{"method":"GET","path":"/api/orders","description":"Get orders for authenticated user; status may be awaiting_tracking (JTL prep, no tracking yet) or ready_for_pickup (Abholung prepared upstream). See docs/frontend-order-status.md; shop uses Socket.IO getOrders.","authentication":"API Key required","headers":{"X-API-Key":"Your API key (or use ?api_key=YOUR_KEY)"},"response":{"success":true,"orders":[{"orderId":"string","status":"string (includes awaiting_tracking, ready_for_pickup)","created_at":"ISO 8601 date","items":[]}]}},{"method":"GET","path":"/api/categories","description":"Get all shop categories (simplified: id + name only)","authentication":"None","response":{"success":true,"categories":[{"id":"number","name":"string"}]}},{"method":"GET","path":"/api/categories/:categoryId/products","description":"Get product list for category (id + name only)","authentication":"None","parameters":{"categoryId":"Category ID (number)"},"response":{"success":true,"products":[{"id":"number","name":"string"}]}},{"method":"GET","path":"/api/products/:productId","description":"Get essential product information","authentication":"None","parameters":{"productId":"Product ID (number)"},"response":{"success":true,"product":{"categoryId":"number","id":"number","name":"string","gtin":"string","vat":"number","price":"number","available":"number (0 or 1)","articleNumber":"string"}}},{"method":"GET","path":"/api/categoryPic/:kBild.jpg","description":"Get category picture as JPEG image (130x130px, white background for transparency)","authentication":"None","parameters":{"kBild":"Category picture ID (number)"},"response":"JPEG image file","cache":{"Cache-Control":"public, max-age=31536000, immutable","Content-Type":"image/jpeg","ETag":"\"{kBild}-{size}\" for conditional requests","Expires":"1 year from request"}},{"method":"HEAD","path":"/api/categoryPic/:kBild.jpg","description":"Check if category picture exists (headers only, no image data)","authentication":"None","parameters":{"kBild":"Category picture ID (number)"},"response":"HTTP headers only","note":"Same caching headers as GET, useful for checking existence without downloading"},{"method":"POST","path":"/api/telemetry/js-errors","description":"Client-reported browser JavaScript errors; stored as NDJSON under logs/telemetry/js-errors/<YYYY-MM-DD>/errors.jsonl. No auth. See docs/telemetry-js-errors.md.","authentication":"None","body":{"message":"string (required) or use errors: [{ message, stack?, ... }]","stack":"string (optional)","name":"string (optional)","filename":"string (optional, or source)","lineno":"number (optional)","colno":"number (optional)","url":"string (optional, or pageUrl)","userAgent":"string (optional; defaults from request header)","context":"object (optional, or extra)"},"response":{"success":true,"accepted":"number of lines written"}}],"authentication":{"description":"Some endpoints require API key authentication","methods":[{"type":"Header","example":"X-API-Key: your-api-key-here"},{"type":"Query Parameter","example":"?api_key=your-api-key-here"}],"obtainKey":"Use the Socket.IO event \"createApiKey\" when authenticated to generate an API key"}}