{"openapi":"3.1.0","info":{"title":"Sarvyam API","version":"1.0.0","description":"Read and write your Sarvyam data — clients, inquiries, quotes, bookings and payments — and receive webhooks when things happen.\n\n**Authentication:** create a key in Settings → Developers and send it as `Authorization: Bearer sk_live_…`. Read keys may only use GET.\n\n**Money** is always an integer in minor units of the business currency. **Dates** without time are `YYYY-MM-DD` in the business timezone.\n\n**Limits:** 300 requests per minute per key. **Errors** return `{ \"error\": { \"code\", \"message\" } }` with a stable `code`."},"servers":[{"url":"https://api.sarvyam.com/v1"}],"security":[{"apiKey":[]}],"tags":[{"name":"Business"},{"name":"Clients"},{"name":"Inquiries"},{"name":"Quotes"},{"name":"Bookings"},{"name":"Payments"},{"name":"Catalog"},{"name":"Webhooks"}],"paths":{"/org":{"get":{"tags":["Business"],"summary":"The business this key belongs to","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"$ref":"#/components/schemas/Business"}}}}}},"401":{"$ref":"#/components/responses/Error"}}}},"/clients":{"get":{"tags":["Clients"],"summary":"List clients","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Search name, email or phone"},{"name":"archived","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"clients":{"type":"array","items":{"$ref":"#/components/schemas/Client"}}}}}}},"401":{"$ref":"#/components/responses/Error"}}},"post":{"tags":["Clients"],"summary":"Create a client","description":"Create a client. Needs a **write** key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientInput"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"$ref":"#/components/schemas/Client"}}}}}},"400":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"}}}},"/clients/{id}":{"get":{"tags":["Clients"],"summary":"Get a client with their quotes and bookings","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"$ref":"#/components/responses/Error"}}},"patch":{"tags":["Clients"],"summary":"Update a client","description":"Update a client. Needs a **write** key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"client":{"$ref":"#/components/schemas/Client"}}}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/leads":{"get":{"tags":["Inquiries"],"summary":"List inquiries","parameters":[{"name":"stage","in":"query","required":false,"schema":{"type":"string","enum":["new","contacted","quoted","won","lost"]}},{"name":"archived","in":"query","required":false,"schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"leads":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}}}}}}}}},"post":{"tags":["Inquiries"],"summary":"Create an inquiry (e.g. from your own form)","description":"Create an inquiry (e.g. from your own form). Needs a **write** key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadInput"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"lead":{"$ref":"#/components/schemas/Lead"}}}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/leads/{id}":{"get":{"tags":["Inquiries"],"summary":"Get an inquiry","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/quotes":{"get":{"tags":["Quotes"],"summary":"List quotes","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","sent","viewed","accepted","declined","expired","void"]}},{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"clientId","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"quotes":{"type":"array","items":{"$ref":"#/components/schemas/Quote"}}}}}}}}},"post":{"tags":["Quotes"],"summary":"Create a draft quote from packages","description":"Create a draft quote from packages. Needs a **write** key.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"clientId":{"type":"string","example":"cmvd1x2y3000abc"},"client":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"}},"description":"Creates or matches a client when clientId is not given."},"leadId":{"type":"string","example":"cmvd1x2y3000abc"},"eventDate":{"type":"string","format":"date","example":"2026-12-17"},"venue":{"type":"string"},"guestCount":{"type":"integer"},"packages":{"type":"array","items":{"type":"object","properties":{"packageId":{"type":"string","example":"cmvd1x2y3000abc"},"quantity":{"type":"string","example":"1"}}}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"quote":{"$ref":"#/components/schemas/Quote"}}}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"}}}},"/quotes/{id}":{"get":{"tags":["Quotes"],"summary":"Get a quote with its lines and totals","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/quotes/{id}/send":{"post":{"tags":["Quotes"],"summary":"Issue the quote (freezes a version) and optionally email the client","description":"Issue the quote (freezes a version) and optionally email the client. Needs a **write** key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"boolean","default":false},"message":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"}}}},"/events":{"get":{"tags":["Bookings"],"summary":"List bookings","parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["tentative","confirmed","completed","cancelled"]}},{"name":"clientId","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/Booking"}}}}}}}}}},"/events/{id}":{"get":{"tags":["Bookings"],"summary":"Get a booking with payments, schedule and tasks","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"$ref":"#/components/responses/Error"}}}},"/events/{id}/payments":{"post":{"tags":["Payments"],"summary":"Record a payment or refund on a booking","description":"Record a payment or refund on a booking. Needs a **write** key.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["amountMinor","method"],"properties":{"amountMinor":{"type":"integer","description":"Amount in minor units (cents, paise…) of the business currency."},"method":{"type":"string","example":"bank_transfer"},"kind":{"type":"string","enum":["payment","refund"],"default":"payment"},"receivedAt":{"type":"string","format":"date-time"},"reference":{"type":"string"},"note":{"type":"string"},"milestoneId":{"type":"string","example":"cmvd1x2y3000abc"}}}}}},"responses":{"201":{"description":"Recorded","content":{"application/json":{"schema":{"type":"object"}}}},"409":{"$ref":"#/components/responses/Error"}}}},"/payments":{"get":{"tags":["Payments"],"summary":"All payments and refunds (newest first, up to 1000)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"payments":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}}}}}}}}}},"/catalog":{"get":{"tags":["Catalog"],"summary":"Catalog items with costs","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/packages":{"get":{"tags":["Catalog"],"summary":"Packages with their recipes and prices","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/exports/{name}.csv":{"get":{"tags":["Business"],"summary":"Download a CSV export","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","enum":["clients","leads","quotes","bookings","payments"]}}],"responses":{"200":{"description":"CSV file","content":{"text/csv":{}}}}}}},"webhooks":{"lead.created":{"post":{"tags":["Webhooks"],"summary":"lead.created","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"client.created":{"post":{"tags":["Webhooks"],"summary":"client.created","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"quote.sent":{"post":{"tags":["Webhooks"],"summary":"quote.sent","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"quote.accepted":{"post":{"tags":["Webhooks"],"summary":"quote.accepted","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"quote.declined":{"post":{"tags":["Webhooks"],"summary":"quote.declined","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"booking.created":{"post":{"tags":["Webhooks"],"summary":"booking.created","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"booking.cancelled":{"post":{"tags":["Webhooks"],"summary":"booking.cancelled","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"payment.received":{"post":{"tags":["Webhooks"],"summary":"payment.received","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}},"gallery.selection_submitted":{"post":{"tags":["Webhooks"],"summary":"gallery.selection_submitted","description":"Sent as POST with JSON body. Verify the `Sarvyam-Signature` header: `t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(your endpoint secret, `${t}.${rawBody}`). Reject timestamps older than 5 minutes. Respond 2xx within 10 s; otherwise we retry with backoff (1 m, 5 m, 30 m, 2 h, 6 h, 12 h, 24 h).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"200":{"description":"Received"}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"sk_live_… key from Settings → Developers"}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"not_found"},"message":{"type":"string"}}}}}}}}},"schemas":{"Business":{"type":"object","properties":{"id":{"type":"string","example":"cmvd1x2y3000abc"},"name":{"type":"string"},"slug":{"type":"string"},"currency":{"type":"string","example":"USD"},"timezone":{"type":"string","example":"America/New_York"},"locale":{"type":"string","example":"en"},"plan":{"type":"string"}}},"ClientInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string","description":"International format preferred, e.g. +44 7700 900123"},"company":{"type":"string"},"address":{"type":"string"},"notes":{"type":"string"},"marketingConsent":{"type":"boolean"},"force":{"type":"boolean","description":"Create even if a client with the same email/phone exists (otherwise 409 possible_duplicate)."}}},"Client":{"type":"object","properties":{"id":{"type":"string","example":"cmvd1x2y3000abc"},"name":{"type":"string"},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"LeadInput":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"eventType":{"type":"string"},"eventDate":{"type":"string","format":"date","example":"2026-12-17"},"venue":{"type":"string"},"guestCount":{"type":"integer"},"budgetMinor":{"type":"integer","description":"Amount in minor units (cents, paise…) of the business currency."},"message":{"type":"string"},"source":{"type":"string","enum":["website","instagram","facebook","whatsapp","referral","phone","walk_in","other"]},"followUpAt":{"type":"string","format":"date-time"}}},"Lead":{"type":"object","properties":{"id":{"type":"string","example":"cmvd1x2y3000abc"},"name":{"type":"string"},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"eventType":{"type":"string","nullable":true},"eventDate":{"type":"string","format":"date","example":"2026-12-17","nullable":true},"stage":{"type":"string"},"source":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"Quote":{"type":"object","properties":{"id":{"type":"string","example":"cmvd1x2y3000abc"},"number":{"type":"string","example":"Q-0042"},"title":{"type":"string"},"status":{"type":"string","enum":["draft","sent","viewed","accepted","declined","expired","void"]},"currency":{"type":"string"},"totalMinor":{"type":"integer","description":"Amount in minor units (cents, paise…) of the business currency."},"eventDate":{"type":"string","format":"date","example":"2026-12-17","nullable":true},"clientId":{"type":"string","example":"cmvd1x2y3000abc"}}},"Booking":{"type":"object","properties":{"id":{"type":"string","example":"cmvd1x2y3000abc"},"title":{"type":"string"},"status":{"type":"string","enum":["tentative","confirmed","completed","cancelled"]},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"totalMinor":{"type":"integer","description":"Amount in minor units (cents, paise…) of the business currency."},"currency":{"type":"string"},"clientId":{"type":"string","example":"cmvd1x2y3000abc"},"quoteId":{"type":"string","example":"cmvd1x2y3000abc","nullable":true}}},"Payment":{"type":"object","properties":{"id":{"type":"string","example":"cmvd1x2y3000abc"},"eventId":{"type":"string","example":"cmvd1x2y3000abc"},"amountMinor":{"type":"integer","description":"Amount in minor units (cents, paise…) of the business currency."},"currency":{"type":"string"},"kind":{"type":"string","enum":["payment","refund"]},"method":{"type":"string"},"receivedAt":{"type":"string","format":"date-time"},"reference":{"type":"string","nullable":true}}},"WebhookEvent":{"type":"object","properties":{"id":{"type":"string","example":"evt_m1abc23"},"type":{"type":"string","enum":["lead.created","client.created","quote.sent","quote.accepted","quote.declined","booking.created","booking.cancelled","payment.received","gallery.selection_submitted","test"]},"created":{"type":"string","format":"date-time"},"data":{"type":"object","description":"Depends on the event type."}}}}}}