Starter packs for 6 event trades — your prices, recipes and checklists, ready on day one. See yours →
Developers

Connect Sarvyam to everything else

A REST API for clients, inquiries, quotes, bookings and payments, and signed webhooks the moment a quote is accepted or a payment lands. Available on Pro and Studio.

Get started in two minutes

  1. In Sarvyam, open Settings → Developers and create a key. Choose read for reporting, write to create clients, inquiries, quotes or payments.
  2. Send it as a bearer token. Keys are shown once — store them like passwords.
curl https://api.sarvyam.com/v1/quotes?status=sent \
  -H "Authorization: Bearer sk_live_…"
  • Base URL: https://api.sarvyam.com/v1 · Spec: openapi.json (import into Postman, Insomnia or a code generator)
  • Money is an integer in minor units of the business currency (cents, paise…). Dates are YYYY-MM-DD in the business timezone.
  • Limit: 300 requests per minute per key. Errors return { "error": { "code", "message" } } with a stable code.
  • Keys cannot reach billing, team, other keys or the account — only business data.

Webhooks

Add an endpoint in Settings → Developers → Webhooks and pick events: lead.created, client.created, quote.sent, quote.accepted, quote.declined, booking.created, booking.cancelled, payment.received, gallery.selection_submitted. Each delivery is a JSON POST; respond 2xx within 10 seconds. Failures retry after 1 m, 5 m, 30 m, 2 h, 6 h, 12 h and 24 h. Every delivery is in the log with its response, and you can resend any of them.

Verify the signature (Node.js)

import crypto from 'node:crypto'

// Express: use the raw body, not the parsed JSON.
app.post('/sarvyam-webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const header = req.get('Sarvyam-Signature') ?? ''        // t=1760000000,v1=ab12…
  const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')))
  const expected = crypto.createHmac('sha256', process.env.SARVYAM_WEBHOOK_SECRET)
    .update(`${t}.${req.body}`).digest('hex')
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300
  if (!fresh || !crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected))) return res.sendStatus(400)
  const event = JSON.parse(req.body)                      // { id, type, created, data }
  // …handle event.type: quote.accepted, payment.received, …
  res.sendStatus(200)
})

Python

import hmac, hashlib, time

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return abs(time.time() - int(parts["t"])) < 300 and hmac.compare_digest(parts["v1"], expected)

Using Zapier or Make? Point a “Catch hook” URL at Sarvyam and use the API key for actions. Questions: support@sarvyam.com.

API reference

Sarvyam API

Read and write your Sarvyam data — clients, inquiries, quotes, bookings and payments — and receive webhooks when things happen.

Authentication: create a key in Settings → Developers and send it as Authorization: Bearer sk_live_…. Read keys may only use GET.

Money is always an integer in minor units of the business currency. Dates without time are YYYY-MM-DD in the business timezone.

Limits: 300 requests per minute per key. Errors return { "error": { "code", "message" } } with a stable code.

Base URL
https://api.sarvyam.com/v1
Authentication
Authorization: Bearer sk_live_…

Business

The business this key belongs to

GET/org

Responses

  • 200OK
  • 401Error
Request
curl https://api.sarvyam.com/v1/org \
  -H "Authorization: Bearer sk_live_…"
Response · 200
{
  "org": {
    "id": "cmvd1x2y3000abc",
    "name": "string",
    "slug": "string",
    "currency": "USD",
    "timezone": "America/New_York",
    "locale": "en",
    "plan": "string"
  }
}

Download a CSV export

GET/exports/{name}.csv

Parameters

  • namepath · stringrequired
    One of clientsleadsquotesbookingspayments

Responses

  • 200CSV file
Request
curl https://api.sarvyam.com/v1/exports/clients.csv \
  -H "Authorization: Bearer sk_live_…"

Clients

List clients

GET/clients

Parameters

  • qquery · string

    Search name, email or phone

  • archivedquery · string
    One of truefalse

Responses

  • 200OK
  • 401Error
Request
curl https://api.sarvyam.com/v1/clients \
  -H "Authorization: Bearer sk_live_…"
Response · 200
{
  "clients": [
    {
      "id": "cmvd1x2y3000abc",
      "name": "string",
      "email": "string",
      "phone": "string",
      "company": "string",
      "createdAt": "2026-12-17T15:00:00.000Z"
    }
  ]
}

Create a client

POST/clients

Create a client. Needs a write key.

Request body

  • namestringrequired
  • emailstring
  • phonestring

    International format preferred, e.g. +44 7700 900123

  • companystring
  • addressstring
  • notesstring
  • marketingConsentboolean
  • forceboolean

    Create even if a client with the same email/phone exists (otherwise 409 possible_duplicate).

Responses

  • 201Created
  • 400Error
  • 409Error
Request
curl -X POST https://api.sarvyam.com/v1/clients \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","email":"string","phone":"string","company":"string","address":"string","notes":"string","marketingConsent":true,"force":true}'
Response · 201
{
  "client": {
    "id": "cmvd1x2y3000abc",
    "name": "string",
    "email": "string",
    "phone": "string",
    "company": "string",
    "createdAt": "2026-12-17T15:00:00.000Z"
  }
}

Get a client with their quotes and bookings

GET/clients/{id}

Parameters

  • idpath · stringrequired

    ID

Responses

  • 200OK
  • 404Error
Request
curl https://api.sarvyam.com/v1/clients/<id> \
  -H "Authorization: Bearer sk_live_…"

Update a client

PATCH/clients/{id}

Update a client. Needs a write key.

Parameters

  • idpath · stringrequired

    ID

Request body

  • namestringrequired
  • emailstring
  • phonestring

    International format preferred, e.g. +44 7700 900123

  • companystring
  • addressstring
  • notesstring
  • marketingConsentboolean
  • forceboolean

    Create even if a client with the same email/phone exists (otherwise 409 possible_duplicate).

Responses

  • 200OK
  • 404Error
Request
curl -X PATCH https://api.sarvyam.com/v1/clients/<id> \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","email":"string","phone":"string","company":"string","address":"string","notes":"string","marketingConsent":true,"force":true}'
Response · 200
{
  "client": {
    "id": "cmvd1x2y3000abc",
    "name": "string",
    "email": "string",
    "phone": "string",
    "company": "string",
    "createdAt": "2026-12-17T15:00:00.000Z"
  }
}

Inquiries

List inquiries

GET/leads

Parameters

  • stagequery · string
    One of newcontactedquotedwonlost
  • archivedquery · string
    One of truefalse

Responses

  • 200OK
Request
curl https://api.sarvyam.com/v1/leads \
  -H "Authorization: Bearer sk_live_…"
Response · 200
{
  "leads": [
    {
      "id": "cmvd1x2y3000abc",
      "name": "string",
      "email": "string",
      "phone": "string",
      "eventType": "string",
      "eventDate": "2026-12-17",
      "stage": "string",
      "source": "string",
      "createdAt": "2026-12-17T15:00:00.000Z"
    }
  ]
}

Create an inquiry (e.g. from your own form)

POST/leads

Create an inquiry (e.g. from your own form). Needs a write key.

Request body

  • namestringrequired
  • emailstring
  • phonestring
  • eventTypestring
  • eventDatestring · date
  • venuestring
  • guestCountinteger
  • budgetMinorinteger

    Amount in minor units (cents, paise…) of the business currency.

  • messagestring
  • sourcestring
    One of websiteinstagramfacebookwhatsappreferralphonewalk_inother
  • followUpAtstring · date-time

Responses

  • 201Created
  • 400Error
Request
curl -X POST https://api.sarvyam.com/v1/leads \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","email":"string","phone":"string","eventType":"string","eventDate":"2026-12-17","venue":"string","guestCount":0,"budgetMinor":0,"message":"string","source":"website","followUpAt":"2026-12-17T15:00:00.000Z"}'
Response · 201
{
  "lead": {
    "id": "cmvd1x2y3000abc",
    "name": "string",
    "email": "string",
    "phone": "string",
    "eventType": "string",
    "eventDate": "2026-12-17",
    "stage": "string",
    "source": "string",
    "createdAt": "2026-12-17T15:00:00.000Z"
  }
}

Get an inquiry

GET/leads/{id}

Parameters

  • idpath · stringrequired

    ID

Responses

  • 200OK
  • 404Error
Request
curl https://api.sarvyam.com/v1/leads/<id> \
  -H "Authorization: Bearer sk_live_…"

Quotes

List quotes

GET/quotes

Parameters

  • statusquery · string
    One of draftsentviewedaccepteddeclinedexpiredvoid
  • qquery · string
  • clientIdquery · string

Responses

  • 200OK
Request
curl https://api.sarvyam.com/v1/quotes \
  -H "Authorization: Bearer sk_live_…"
Response · 200
{
  "quotes": [
    {
      "id": "cmvd1x2y3000abc",
      "number": "Q-0042",
      "title": "string",
      "status": "draft",
      "currency": "string",
      "totalMinor": 0,
      "eventDate": "2026-12-17",
      "clientId": "cmvd1x2y3000abc"
    }
  ]
}

Create a draft quote from packages

POST/quotes

Create a draft quote from packages. Needs a write key.

Request body

  • titlestringrequired
  • clientIdstring
  • clientobject

    Creates or matches a client when clientId is not given.

    Fields
    • namestring
    • emailstring
    • phonestring
  • leadIdstring
  • eventDatestring · date
  • venuestring
  • guestCountinteger
  • packagesobject[]
    Fields
    • packageIdstring
    • quantitystring

Responses

  • 201Created
  • 400Error
  • 402Error
Request
curl -X POST https://api.sarvyam.com/v1/quotes \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"title":"string","clientId":"cmvd1x2y3000abc","client":{"name":"string","email":"string","phone":"string"},"leadId":"cmvd1x2y3000abc","eventDate":"2026-12-17","venue":"string","guestCount":0,"packages":[{"packageId":"cmvd1x2y3000abc","quantity":"1"}]}'
Response · 201
{
  "quote": {
    "id": "cmvd1x2y3000abc",
    "number": "Q-0042",
    "title": "string",
    "status": "draft",
    "currency": "string",
    "totalMinor": 0,
    "eventDate": "2026-12-17",
    "clientId": "cmvd1x2y3000abc"
  }
}

Get a quote with its lines and totals

GET/quotes/{id}

Parameters

  • idpath · stringrequired

    ID

Responses

  • 200OK
  • 404Error
Request
curl https://api.sarvyam.com/v1/quotes/<id> \
  -H "Authorization: Bearer sk_live_…"

Issue the quote (freezes a version) and optionally email the client

POST/quotes/{id}/send

Issue the quote (freezes a version) and optionally email the client. Needs a write key.

Parameters

  • idpath · stringrequired

    ID

Request body

  • emailboolean
    Default false
  • messagestring

Responses

  • 200OK
  • 400Error
  • 402Error
Request
curl -X POST https://api.sarvyam.com/v1/quotes/<id>/send \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"email":false,"message":"string"}'

Bookings

List bookings

GET/events

Parameters

  • fromquery · string · date-time
  • toquery · string · date-time
  • statusquery · string
    One of tentativeconfirmedcompletedcancelled
  • clientIdquery · string

Responses

  • 200OK
Request
curl https://api.sarvyam.com/v1/events \
  -H "Authorization: Bearer sk_live_…"
Response · 200
{
  "events": [
    {
      "id": "cmvd1x2y3000abc",
      "title": "string",
      "status": "tentative",
      "startsAt": "2026-12-17T15:00:00.000Z",
      "endsAt": "2026-12-17T15:00:00.000Z",
      "totalMinor": 0,
      "currency": "string",
      "clientId": "cmvd1x2y3000abc",
      "quoteId": "cmvd1x2y3000abc"
    }
  ]
}

Get a booking with payments, schedule and tasks

GET/events/{id}

Parameters

  • idpath · stringrequired

    ID

Responses

  • 200OK
  • 404Error
Request
curl https://api.sarvyam.com/v1/events/<id> \
  -H "Authorization: Bearer sk_live_…"

Payments

Record a payment or refund on a booking

POST/events/{id}/payments

Record a payment or refund on a booking. Needs a write key.

Parameters

  • idpath · stringrequired

    ID

Request body

  • amountMinorintegerrequired

    Amount in minor units (cents, paise…) of the business currency.

  • methodstringrequired
  • kindstring
    One of paymentrefund
    Default "payment"
  • receivedAtstring · date-time
  • referencestring
  • notestring
  • milestoneIdstring

Responses

  • 201Recorded
  • 409Error
Request
curl -X POST https://api.sarvyam.com/v1/events/<id>/payments \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"amountMinor":0,"method":"bank_transfer","kind":"payment","receivedAt":"2026-12-17T15:00:00.000Z","reference":"string","note":"string","milestoneId":"cmvd1x2y3000abc"}'

All payments and refunds (newest first, up to 1000)

GET/payments

Responses

  • 200OK
Request
curl https://api.sarvyam.com/v1/payments \
  -H "Authorization: Bearer sk_live_…"
Response · 200
{
  "payments": [
    {
      "id": "cmvd1x2y3000abc",
      "eventId": "cmvd1x2y3000abc",
      "amountMinor": 0,
      "currency": "string",
      "kind": "payment",
      "method": "string",
      "receivedAt": "2026-12-17T15:00:00.000Z",
      "reference": "string"
    }
  ]
}

Catalog

Catalog items with costs

GET/catalog

Responses

  • 200OK
Request
curl https://api.sarvyam.com/v1/catalog \
  -H "Authorization: Bearer sk_live_…"

Packages with their recipes and prices

GET/packages

Responses

  • 200OK
Request
curl https://api.sarvyam.com/v1/packages \
  -H "Authorization: Bearer sk_live_…"

Webhooks

lead.created

eventlead.created

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

client.created

eventclient.created

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

quote.sent

eventquote.sent

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

quote.accepted

eventquote.accepted

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

quote.declined

eventquote.declined

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

booking.created

eventbooking.created

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

booking.cancelled

eventbooking.cancelled

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}

payment.received

eventpayment.received

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).

Payload

  • idstring
  • typestring
    One of lead.createdclient.createdquote.sentquote.acceptedquote.declinedbooking.createdbooking.cancelledpayment.receivedgallery.selection_submittedtest
  • createdstring · date-time
  • dataobject

    Depends on the event type.

Responses

  • 200Received
Payload
{
  "id": "evt_m1abc23",
  "type": "lead.created",
  "created": "2026-12-17T15:00:00.000Z",
  "data": {}
}