{"openapi":"3.1.0","info":{"title":"Quilo API","version":"1.0.0","description":"REST API for Quilo by TeknoCare. Authenticate with a personal API key: `Authorization: Bearer qk_…`. Guides: /developers.","contact":{"name":"TeknoCare support","url":"https://quilo-ninga.com/developers/support"}},"servers":[{"url":"https://quilo-ninga.com/api/v1"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"qk_<10 hex>_<32 chars>","description":"Personal API key from Settings → API keys."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["type","message"],"properties":{"type":{"type":"string","enum":["invalid_request","authentication_failed","permission_denied","insufficient_scope","not_found","conflict","validation_failed","rate_limited","server_error"]},"message":{"type":"string"},"request_id":{"type":"string","example":"req_3f9a1c0b7d2e4a65"},"errors":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"message":{"type":"string"}}}}}}}},"Client":{"type":"object","properties":{"object":{"type":"string","const":"client"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"first_name":{"description":"First name.","type":"string","maxLength":100,"example":"Elena"},"last_name":{"description":"Last name.","type":"string","maxLength":100,"example":"Marti"},"company_name":{"description":"Company, for business clients.","type":"string","maxLength":200},"email":{"description":"Email address.","type":"string","format":"email","maxLength":254,"example":"elena@example.ch"},"phone":{"description":"Phone in any format; international (+41…) works best.","type":"string","maxLength":40,"example":"+41 79 123 45 67"},"street":{"description":"Street.","type":"string","maxLength":200},"house_no":{"description":"House number.","type":"string","maxLength":20},"zip":{"description":"Postcode.","type":"string","maxLength":20},"city":{"description":"Town or city.","type":"string","maxLength":100},"country":{"description":"Country as a two-letter code (CH, DE, AE…).","type":"string","maxLength":2,"example":"CH"},"external_code":{"description":"Your own client number, e.g. from Lightspeed or a website.","type":"string","maxLength":60},"ring_size":{"description":"Ring size.","type":"string","maxLength":20},"metal":{"description":"Preferred metal.","type":"string","maxLength":60},"stones":{"description":"Preferred stones.","type":"string","maxLength":120},"style":{"description":"Style notes.","type":"string","maxLength":120},"birthday":{"description":"Birthday (YYYY-MM-DD).","type":"string","format":"date","example":"1990-04-12"},"anniversary":{"description":"Anniversary (YYYY-MM-DD).","type":"string","format":"date"},"tags":{"description":"Up to 30 tags of up to 40 characters.","type":"array","items":{"type":"string","maxLength":40},"maxItems":30,"example":["vip","website"]},"notes":{"description":"Free notes.","type":"string","maxLength":5000},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"},"updated_at":{"description":"When it was last changed.","type":"string","format":"date-time","readOnly":true}}},"Sale":{"type":"object","properties":{"object":{"type":"string","const":"sale"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":"string","format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"purchased_on":{"description":"Date of the sale (YYYY-MM-DD). Default: today.","type":"string","format":"date","example":"2026-10-17"},"receipt_no":{"description":"Receipt or order number; unique per brand.","type":"string","maxLength":60,"example":"W-10442"},"items":{"description":"What was sold, as text.","type":"string","maxLength":2000,"example":"18k gold ring, sapphire"},"total":{"description":"Total amount in the brand currency.","type":"number","minimum":0,"maximum":10000000,"example":2480},"channel":{"description":"Where it was sold: store, website, phone…","type":"string","maxLength":40,"example":"website"},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"}}},"CustomOrder":{"type":"object","properties":{"object":{"type":"string","const":"custom_order"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":"string","format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What is being made.","type":"string","maxLength":200,"example":"Engagement ring, oval diamond"},"stage":{"description":"Current stage. Default: inquiry.","type":"string","enum":["inquiry","design","deposit","production","ready","won","lost"],"example":"design"},"value":{"description":"Expected value.","type":"number","minimum":0,"maximum":10000000,"example":6500},"deposit":{"description":"Deposit received.","type":"number","minimum":0,"maximum":10000000,"example":2000},"due_on":{"description":"Promised date (YYYY-MM-DD).","type":"string","format":"date"},"notes":{"description":"Notes.","type":"string","maxLength":5000},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"}}},"Appointment":{"type":"object","properties":{"object":{"type":"string","const":"appointment"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":"string","format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What the appointment is.","type":"string","maxLength":200,"example":"Ring fitting"},"starts_at":{"description":"Start, ISO 8601 with time zone.","type":"string","format":"date-time","example":"2026-10-20T14:00:00+02:00"},"ends_at":{"description":"End, ISO 8601 with time zone.","type":"string","format":"date-time","example":"2026-10-20T14:45:00+02:00"},"status":{"description":"Default: active.","type":"string","enum":["active","cancelled","completed","no_show"]},"source":{"description":"Where it came from: quilo, calendly, google or api.","type":"string","readOnly":true},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"}}},"Task":{"type":"object","properties":{"object":{"type":"string","const":"task"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":"string","format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What needs doing.","type":"string","maxLength":200,"example":"Call Elena about the sapphire"},"description":{"description":"Details.","type":"string","maxLength":5000},"status":{"description":"Default: todo.","type":"string","enum":["todo","progress","review","done"],"example":"todo"},"priority":{"description":"Default: normal.","type":"string","enum":["urgent","high","normal","low"]},"due_on":{"description":"Due date (YYYY-MM-DD).","type":"string","format":"date","example":"2026-10-21"},"estimate_minutes":{"description":"Estimated minutes.","type":"integer","minimum":0,"maximum":100000},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"}}},"Invoice":{"type":"object","properties":{"object":{"type":"string","const":"invoice"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","readOnly":true,"example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":"string","format":"uuid","readOnly":true,"example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"number":{"description":"Invoice number.","type":"string","readOnly":true,"example":"DJ-2026-042"},"issued_on":{"description":"Issue date.","type":"string","format":"date","readOnly":true},"due_on":{"description":"Due date.","type":"string","format":"date","readOnly":true},"status":{"description":"Status.","type":"string","enum":["draft","sent","paid","void"],"readOnly":true},"currency":{"description":"Currency.","type":"string","readOnly":true,"example":"CHF"},"vat_rate":{"description":"VAT rate in percent.","type":"number","readOnly":true,"example":8.1},"prices_incl_vat":{"description":"Whether line prices include VAT.","type":"boolean","readOnly":true},"qr_reference":{"description":"QR-bill reference.","type":"string","readOnly":true},"paid_on":{"description":"When it was paid.","type":"string","format":"date","readOnly":true},"notes":{"description":"Notes on the invoice.","type":"string","readOnly":true},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"}}},"Brand":{"type":"object","properties":{"object":{"type":"string","const":"brand"},"id":{"description":"Unique ID.","type":"string","format":"uuid","readOnly":true,"example":"6f1c2a90-3b4d-4e5f-8a7b-9c0d1e2f3a4b"},"name":{"description":"Brand name.","type":"string","readOnly":true,"example":"Dubai Jewellery"},"prefix":{"description":"Invoice number prefix.","type":"string","readOnly":true},"currency":{"description":"Currency.","type":"string","readOnly":true,"example":"CHF"},"country":{"description":"Country code.","type":"string","readOnly":true},"archived":{"description":"Archived brands are read-only.","type":"boolean","readOnly":true},"created_at":{"description":"When it was created (UTC, ISO 8601).","type":"string","format":"date-time","readOnly":true,"example":"2026-10-17T09:30:00Z"}}}}},"tags":[{"name":"Account"},{"name":"Clients","description":"People and companies who buy from you, with contact details, preferences (ring size, metal, stones, style) and dates."},{"name":"Sales","description":"What clients bought: date, receipt number, items and total. A receipt number is unique per brand."},{"name":"Custom orders","description":"Made-to-order pieces moving through stages from inquiry to won or lost."},{"name":"Appointments","description":"Visits, calls and fittings. Appointments created through the API are marked with source \"api\"."},{"name":"Tasks & follow-ups","description":"To-dos and follow-ups, optionally linked to a client."},{"name":"Invoices","description":"Invoices with Swiss QR-bill reference (read only in v1). GET /invoices/{id} includes the lines."},{"name":"Brands","description":"The brands (shops, labels) of the company that you can access. Use their IDs as brand_id."}],"paths":{"/clients":{"get":{"tags":["Clients"],"summary":"List clients","description":"People and companies who buy from you, with contact details, preferences (ring size, metal, stones, style) and dates.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"brand_id","in":"query","description":"Only this brand.","schema":{"description":"Only this brand.","type":"string","format":"uuid"}},{"name":"email","in":"query","description":"Exact email address (not case-sensitive).","schema":{"description":"Exact email address (not case-sensitive).","type":"string","format":"email"}},{"name":"external_code","in":"query","description":"Exact external code.","schema":{"description":"Exact external code.","type":"string"}},{"name":"q","in":"query","description":"Search in name, company, email and phone.","schema":{"description":"Search in name, company, email and phone.","type":"string"}},{"name":"created_since","in":"query","description":"Created at or after this time.","schema":{"description":"Created at or after this time.","type":"string","format":"date-time"}},{"name":"updated_since","in":"query","description":"Changed at or after this time (use for syncing).","schema":{"description":"Changed at or after this time (use for syncing).","type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Client"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Clients"],"summary":"Create a client","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","minLength":8,"maxLength":100},"description":"Send the same value to retry safely for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"first_name":{"description":"First name.","type":["string","null"],"maxLength":100,"example":"Elena"},"last_name":{"description":"Last name.","type":["string","null"],"maxLength":100,"example":"Marti"},"company_name":{"description":"Company, for business clients.","type":["string","null"],"maxLength":200},"email":{"description":"Email address.","type":["string","null"],"format":"email","maxLength":254,"example":"elena@example.ch"},"phone":{"description":"Phone in any format; international (+41…) works best.","type":["string","null"],"maxLength":40,"example":"+41 79 123 45 67"},"street":{"description":"Street.","type":["string","null"],"maxLength":200},"house_no":{"description":"House number.","type":["string","null"],"maxLength":20},"zip":{"description":"Postcode.","type":["string","null"],"maxLength":20},"city":{"description":"Town or city.","type":["string","null"],"maxLength":100},"country":{"description":"Country as a two-letter code (CH, DE, AE…).","type":["string","null"],"maxLength":2,"example":"CH"},"external_code":{"description":"Your own client number, e.g. from Lightspeed or a website.","type":["string","null"],"maxLength":60},"ring_size":{"description":"Ring size.","type":["string","null"],"maxLength":20},"metal":{"description":"Preferred metal.","type":["string","null"],"maxLength":60},"stones":{"description":"Preferred stones.","type":["string","null"],"maxLength":120},"style":{"description":"Style notes.","type":["string","null"],"maxLength":120},"birthday":{"description":"Birthday (YYYY-MM-DD).","type":["string","null"],"format":"date","example":"1990-04-12"},"anniversary":{"description":"Anniversary (YYYY-MM-DD).","type":["string","null"],"format":"date"},"tags":{"description":"Up to 30 tags of up to 40 characters.","type":["array","null"],"items":{"type":"string","maxLength":40},"maxItems":30,"example":["vip","website"]},"notes":{"description":"Free notes.","type":["string","null"],"maxLength":5000}},"required":["brand_id"]}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate unique value, or Idempotency-Key reused with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/clients/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Clients"],"summary":"Get a client","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Clients"],"summary":"Change a client","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"first_name":{"description":"First name.","type":["string","null"],"maxLength":100,"example":"Elena"},"last_name":{"description":"Last name.","type":["string","null"],"maxLength":100,"example":"Marti"},"company_name":{"description":"Company, for business clients.","type":["string","null"],"maxLength":200},"email":{"description":"Email address.","type":["string","null"],"format":"email","maxLength":254,"example":"elena@example.ch"},"phone":{"description":"Phone in any format; international (+41…) works best.","type":["string","null"],"maxLength":40,"example":"+41 79 123 45 67"},"street":{"description":"Street.","type":["string","null"],"maxLength":200},"house_no":{"description":"House number.","type":["string","null"],"maxLength":20},"zip":{"description":"Postcode.","type":["string","null"],"maxLength":20},"city":{"description":"Town or city.","type":["string","null"],"maxLength":100},"country":{"description":"Country as a two-letter code (CH, DE, AE…).","type":["string","null"],"maxLength":2,"example":"CH"},"external_code":{"description":"Your own client number, e.g. from Lightspeed or a website.","type":["string","null"],"maxLength":60},"ring_size":{"description":"Ring size.","type":["string","null"],"maxLength":20},"metal":{"description":"Preferred metal.","type":["string","null"],"maxLength":60},"stones":{"description":"Preferred stones.","type":["string","null"],"maxLength":120},"style":{"description":"Style notes.","type":["string","null"],"maxLength":120},"birthday":{"description":"Birthday (YYYY-MM-DD).","type":["string","null"],"format":"date","example":"1990-04-12"},"anniversary":{"description":"Anniversary (YYYY-MM-DD).","type":["string","null"],"format":"date"},"tags":{"description":"Up to 30 tags of up to 40 characters.","type":["array","null"],"items":{"type":"string","maxLength":40},"maxItems":30,"example":["vip","website"]},"notes":{"description":"Free notes.","type":["string","null"],"maxLength":5000}},"minProperties":1}}}},"responses":{"200":{"description":"Changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Client"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Clients"],"summary":"Delete a client","description":"Owners, admins and managers only.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string"},"id":{"type":"string"},"deleted":{"const":true}}}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sales":{"get":{"tags":["Sales"],"summary":"List sales","description":"What clients bought: date, receipt number, items and total. A receipt number is unique per brand.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"brand_id","in":"query","description":"Only this brand.","schema":{"description":"Only this brand.","type":"string","format":"uuid"}},{"name":"client_id","in":"query","description":"Only this client.","schema":{"description":"Only this client.","type":"string","format":"uuid"}},{"name":"receipt_no","in":"query","description":"Exact receipt number.","schema":{"description":"Exact receipt number.","type":"string"}},{"name":"purchased_from","in":"query","description":"Sold on or after this date.","schema":{"description":"Sold on or after this date.","type":"string","format":"date"}},{"name":"purchased_to","in":"query","description":"Sold on or before this date.","schema":{"description":"Sold on or before this date.","type":"string","format":"date"}},{"name":"created_since","in":"query","description":"Created at or after this time.","schema":{"description":"Created at or after this time.","type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Sale"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Sales"],"summary":"Create a sale","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","minLength":8,"maxLength":100},"description":"Send the same value to retry safely for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"purchased_on":{"description":"Date of the sale (YYYY-MM-DD). Default: today.","type":["string","null"],"format":"date","example":"2026-10-17"},"receipt_no":{"description":"Receipt or order number; unique per brand.","type":["string","null"],"maxLength":60,"example":"W-10442"},"items":{"description":"What was sold, as text.","type":["string","null"],"maxLength":2000,"example":"18k gold ring, sapphire"},"total":{"description":"Total amount in the brand currency.","type":"number","minimum":0,"maximum":10000000,"example":2480},"channel":{"description":"Where it was sold: store, website, phone…","type":["string","null"],"maxLength":40,"example":"website"}},"required":["brand_id","total"]}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sale"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate unique value, or Idempotency-Key reused with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sales/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Sales"],"summary":"Get a sale","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sale"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Sales"],"summary":"Change a sale","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"purchased_on":{"description":"Date of the sale (YYYY-MM-DD). Default: today.","type":["string","null"],"format":"date","example":"2026-10-17"},"receipt_no":{"description":"Receipt or order number; unique per brand.","type":["string","null"],"maxLength":60,"example":"W-10442"},"items":{"description":"What was sold, as text.","type":["string","null"],"maxLength":2000,"example":"18k gold ring, sapphire"},"total":{"description":"Total amount in the brand currency.","type":["number","null"],"minimum":0,"maximum":10000000,"example":2480},"channel":{"description":"Where it was sold: store, website, phone…","type":["string","null"],"maxLength":40,"example":"website"}},"minProperties":1}}}},"responses":{"200":{"description":"Changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sale"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Sales"],"summary":"Delete a sale","description":"Owners, admins and managers only.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string"},"id":{"type":"string"},"deleted":{"const":true}}}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/custom-orders":{"get":{"tags":["Custom orders"],"summary":"List custom orders","description":"Made-to-order pieces moving through stages from inquiry to won or lost.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"brand_id","in":"query","description":"Only this brand.","schema":{"description":"Only this brand.","type":"string","format":"uuid"}},{"name":"client_id","in":"query","description":"Only this client.","schema":{"description":"Only this client.","type":"string","format":"uuid"}},{"name":"stage","in":"query","description":"Only this stage.","schema":{"type":"string","enum":["inquiry","design","deposit","production","ready","won","lost"]}},{"name":"created_since","in":"query","description":"Created at or after this time.","schema":{"description":"Created at or after this time.","type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/CustomOrder"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Custom orders"],"summary":"Create a custom order","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","minLength":8,"maxLength":100},"description":"Send the same value to retry safely for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What is being made.","type":"string","maxLength":200,"example":"Engagement ring, oval diamond"},"stage":{"description":"Current stage. Default: inquiry.","type":["string","null"],"enum":["inquiry","design","deposit","production","ready","won","lost"],"example":"design"},"value":{"description":"Expected value.","type":["number","null"],"minimum":0,"maximum":10000000,"example":6500},"deposit":{"description":"Deposit received.","type":["number","null"],"minimum":0,"maximum":10000000,"example":2000},"due_on":{"description":"Promised date (YYYY-MM-DD).","type":["string","null"],"format":"date"},"notes":{"description":"Notes.","type":["string","null"],"maxLength":5000}},"required":["brand_id","title"]}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomOrder"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate unique value, or Idempotency-Key reused with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/custom-orders/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Custom orders"],"summary":"Get a custom order","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomOrder"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Custom orders"],"summary":"Change a custom order","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What is being made.","type":["string","null"],"maxLength":200,"example":"Engagement ring, oval diamond"},"stage":{"description":"Current stage. Default: inquiry.","type":["string","null"],"enum":["inquiry","design","deposit","production","ready","won","lost"],"example":"design"},"value":{"description":"Expected value.","type":["number","null"],"minimum":0,"maximum":10000000,"example":6500},"deposit":{"description":"Deposit received.","type":["number","null"],"minimum":0,"maximum":10000000,"example":2000},"due_on":{"description":"Promised date (YYYY-MM-DD).","type":["string","null"],"format":"date"},"notes":{"description":"Notes.","type":["string","null"],"maxLength":5000}},"minProperties":1}}}},"responses":{"200":{"description":"Changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomOrder"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Custom orders"],"summary":"Delete a custom order","description":"Owners, admins and managers only.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string"},"id":{"type":"string"},"deleted":{"const":true}}}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments":{"get":{"tags":["Appointments"],"summary":"List appointments","description":"Visits, calls and fittings. Appointments created through the API are marked with source \"api\".","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"brand_id","in":"query","description":"Only this brand.","schema":{"description":"Only this brand.","type":"string","format":"uuid"}},{"name":"client_id","in":"query","description":"Only this client.","schema":{"description":"Only this client.","type":"string","format":"uuid"}},{"name":"starts_after","in":"query","description":"Starts at or after this time.","schema":{"description":"Starts at or after this time.","type":"string","format":"date-time"}},{"name":"starts_before","in":"query","description":"Starts before this time.","schema":{"description":"Starts before this time.","type":"string","format":"date-time"}},{"name":"status","in":"query","description":"Only this status.","schema":{"type":"string","enum":["active","cancelled","completed","no_show"]}}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Appointment"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Appointments"],"summary":"Create a appointment","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","minLength":8,"maxLength":100},"description":"Send the same value to retry safely for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What the appointment is.","type":"string","maxLength":200,"example":"Ring fitting"},"starts_at":{"description":"Start, ISO 8601 with time zone.","type":"string","format":"date-time","example":"2026-10-20T14:00:00+02:00"},"ends_at":{"description":"End, ISO 8601 with time zone.","type":["string","null"],"format":"date-time","example":"2026-10-20T14:45:00+02:00"},"status":{"description":"Default: active.","type":["string","null"],"enum":["active","cancelled","completed","no_show"]}},"required":["brand_id","title","starts_at"]}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate unique value, or Idempotency-Key reused with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Appointments"],"summary":"Get a appointment","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Appointments"],"summary":"Change a appointment","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What the appointment is.","type":["string","null"],"maxLength":200,"example":"Ring fitting"},"starts_at":{"description":"Start, ISO 8601 with time zone.","type":["string","null"],"format":"date-time","example":"2026-10-20T14:00:00+02:00"},"ends_at":{"description":"End, ISO 8601 with time zone.","type":["string","null"],"format":"date-time","example":"2026-10-20T14:45:00+02:00"},"status":{"description":"Default: active.","type":["string","null"],"enum":["active","cancelled","completed","no_show"]}},"minProperties":1}}}},"responses":{"200":{"description":"Changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Appointments"],"summary":"Delete a appointment","description":"Owners, admins and managers only.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string"},"id":{"type":"string"},"deleted":{"const":true}}}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks":{"get":{"tags":["Tasks & follow-ups"],"summary":"List tasks & follow-ups","description":"To-dos and follow-ups, optionally linked to a client.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"brand_id","in":"query","description":"Only this brand.","schema":{"description":"Only this brand.","type":"string","format":"uuid"}},{"name":"client_id","in":"query","description":"Only this client.","schema":{"description":"Only this client.","type":"string","format":"uuid"}},{"name":"status","in":"query","description":"Only this status.","schema":{"type":"string","enum":["todo","progress","review","done"]}},{"name":"priority","in":"query","description":"Only this priority.","schema":{"type":"string","enum":["urgent","high","normal","low"]}},{"name":"due_before","in":"query","description":"Due on or before this date.","schema":{"description":"Due on or before this date.","type":"string","format":"date"}},{"name":"created_since","in":"query","description":"Created at or after this time.","schema":{"description":"Created at or after this time.","type":"string","format":"date-time"}}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Task"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Tasks & follow-ups"],"summary":"Create a task","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","minLength":8,"maxLength":100},"description":"Send the same value to retry safely for 24 hours."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"brand_id":{"description":"The brand this belongs to (see GET /brands). Required when creating; cannot be changed.","type":"string","format":"uuid","example":"0b7e9a52-1c3d-4f6e-9a8b-7c6d5e4f3a2b"},"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What needs doing.","type":"string","maxLength":200,"example":"Call Elena about the sapphire"},"description":{"description":"Details.","type":["string","null"],"maxLength":5000},"status":{"description":"Default: todo.","type":["string","null"],"enum":["todo","progress","review","done"],"example":"todo"},"priority":{"description":"Default: normal.","type":["string","null"],"enum":["urgent","high","normal","low"]},"due_on":{"description":"Due date (YYYY-MM-DD).","type":["string","null"],"format":"date","example":"2026-10-21"},"estimate_minutes":{"description":"Estimated minutes.","type":["integer","null"],"minimum":0,"maximum":100000}},"required":["brand_id","title"]}}}},"responses":{"201":{"description":"Created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate unique value, or Idempotency-Key reused with a different body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Tasks & follow-ups"],"summary":"Get a task","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Tasks & follow-ups"],"summary":"Change a task","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"client_id":{"description":"The client it belongs to (optional).","type":["string","null"],"format":"uuid","example":"5d2c1b0a-9e8f-4a7b-8c6d-5e4f3a2b1c0d"},"title":{"description":"What needs doing.","type":["string","null"],"maxLength":200,"example":"Call Elena about the sapphire"},"description":{"description":"Details.","type":["string","null"],"maxLength":5000},"status":{"description":"Default: todo.","type":["string","null"],"enum":["todo","progress","review","done"],"example":"todo"},"priority":{"description":"Default: normal.","type":["string","null"],"enum":["urgent","high","normal","low"]},"due_on":{"description":"Due date (YYYY-MM-DD).","type":["string","null"],"format":"date","example":"2026-10-21"},"estimate_minutes":{"description":"Estimated minutes.","type":["integer","null"],"minimum":0,"maximum":100000}},"minProperties":1}}}},"responses":{"200":{"description":"Changed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validation failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Tasks & follow-ups"],"summary":"Delete a task","description":"Owners, admins and managers only.","responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string"},"id":{"type":"string"},"deleted":{"const":true}}}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices":{"get":{"tags":["Invoices"],"summary":"List invoices","description":"Invoices with Swiss QR-bill reference (read only in v1). GET /invoices/{id} includes the lines.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."},{"name":"brand_id","in":"query","description":"Only this brand.","schema":{"description":"Only this brand.","type":"string","format":"uuid"}},{"name":"client_id","in":"query","description":"Only this client.","schema":{"description":"Only this client.","type":"string","format":"uuid"}},{"name":"status","in":"query","description":"Only this status.","schema":{"type":"string","enum":["draft","sent","paid","void"]}},{"name":"issued_from","in":"query","description":"Issued on or after this date.","schema":{"description":"Issued on or after this date.","type":"string","format":"date"}},{"name":"issued_to","in":"query","description":"Issued on or before this date.","schema":{"description":"Issued on or before this date.","type":"string","format":"date"}}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/invoices/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Invoices"],"summary":"Get a invoice","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/brands":{"get":{"tags":["Brands"],"summary":"List brands","description":"The brands (shops, labels) of the company that you can access. Use their IDs as brand_id.","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Items per page."},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"next_cursor from the previous page."}],"responses":{"200":{"description":"A page, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Brand"}},"has_more":{"type":"boolean"},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Unknown or invalid query parameter.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/brands/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Brands"],"summary":"Get a brand","responses":{"200":{"description":"Found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Brand"}}}},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found in your company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/me":{"get":{"tags":["Account"],"summary":"Who this key acts as","description":"Key name, access, person, role, company and brands. Use it to test a new key.","responses":{"200":{"description":"The key, person, company and brands."},"401":{"description":"Missing, invalid, revoked or expired key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Not allowed for this key or person.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached; see Retry-After.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}