API

API & integrations

Connect evSuryam to your CRM, accounting stack, and internal tools with a versioned REST API, real-time webhooks, and pre-built Tally / Zoho Books sync.

11 min read Updated June 2026

The evSuryam API lets you read and write the same data your team works with in the dashboard — customers, quotations, invoices, and inventory — from your own code. It is a conventional, versioned REST API: predictable resource URLs, JSON request and response bodies, bearer-token authentication, and standard HTTP status codes. This page is the orientation map; deep-dive guides like sending invoice events to your accounting system build on it.

Overview & base URL

Every request goes to a single, version-pinned base URL. The version lives in the path so a future v2 never breaks code written against v1.

Base URL: https://api.evsuryam.com/v1

API keys and webhook configuration.
API keys and webhook configuration.

One workspace, one tenantEvery token is scoped to the company that created it. The API only ever returns data for your own workspace — there is no cross-tenant access, and you never pass a company id in requests.

Authentication

The API authenticates with personal access tokens sent as a bearer token in the Authorization header. Generate a token under Settings → API → Tokens:

  1. Open Settings → API → Tokens and click Generate token.
  2. Give it a descriptive name (for example tally-sync-prod) so you can revoke the right one later.
  3. Choose abilities — scope the token to only what it needs, such as invoices:read or inventory:write.
  4. Copy the token immediately. It is shown once and stored only as a hash — if you lose it, revoke and regenerate.

Send it on every request:

curl https://api.evsuryam.com/v1/customers \
      -H "Authorization: Bearer evs_live_9f3c7a1e8b24d6f0a5c1e2b3d4f5a6b7" \
      -H "Accept: application/json"

Treat tokens like passwordsNever commit a token to source control, embed it in a browser app, or log it. Store it in a secrets manager or server environment variable. Revoke any token the moment it may have leaked — revocation is instant.

A missing or invalid token returns 401 Unauthenticated. A valid token that lacks the ability for an endpoint returns 403 Forbidden.

Rate limits & errors

Requests are rate-limited per token. The default ceiling is 120 requests per minute; bulk and sync endpoints carry their own lower limits. Every response includes the current budget in headers:

HeaderMeaning
X-RateLimit-LimitMaximum requests allowed in the current window.
X-RateLimit-RemainingRequests left before you are throttled.
Retry-AfterSeconds to wait, sent only on a 429 response.

When you exceed the limit you receive 429 Too Many Requests. Back off for the number of seconds in Retry-After before retrying. Errors share one envelope across the whole API:

{
  "message": "The given data was invalid.",
  "code": "VALIDATION_FAILED",
  "errors": {
    "email": ["The email field is required."]
  }
}

Match on the stable code string, not on the human-readable message. Common codes: UNAUTHENTICATED (401), FORBIDDEN (403), NOT_FOUND (404), VALIDATION_FAILED (422), and TOO_MANY_REQUESTS (429).

Core resources

The four resources below mirror the heart of the dashboard. Each supports the standard list / read / create / update verbs unless noted.

ResourceEndpointWhat it represents
Customers/v1/customersHomeowners and businesses you sell to, including site address and GSTIN.
Quotations/v1/quotationsPriced proposals with line items, taxes, and validity.
Invoices/v1/invoicesGST-compliant tax invoices with full CGST/SGST/IGST breakdown.
Inventory/v1/inventory/itemsStock of panels, inverters, and BOS, with on-hand quantities.

Standard verbs follow REST conventions:

VerbPathActionSuccess code
GET/v1/invoicesList invoices (paginated)200
GET/v1/invoices/{id}Retrieve one invoice200
POST/v1/invoicesCreate an invoice201
PATCH/v1/invoices/{id}Update an invoice200
GET/v1/customersList customers200
POST/v1/customersCreate a customer201

List endpoints accept ?page and ?per_page (capped at 100), filters such as ?status=paid, sorting with ?sort=-issued_at (leading - for descending), and eager-loading with ?include=customer,line_items.

Example: listing invoices

Fetch the most recent paid invoices, newest first:

curl "https://api.evsuryam.com/v1/invoices?status=paid&sort=-issued_at&per_page=2" \
      -H "Authorization: Bearer evs_live_9f3c7a1e8b24d6f0a5c1e2b3d4f5a6b7" \
      -H "Accept: application/json"

A successful response (200 OK):

{
  "data": [
    {
      "id": "01HF8Z9Q4M2P0T7VBC3K1XR8AD",
      "number": "INV-2026-0184",
      "status": "paid",
      "issued_at": "2026-06-09T11:20:04+05:30",
      "customer": {
        "id": "01HF8Z6Y7N0E5R2QABV9MK3T1C",
        "name": "Anjali Desai",
        "gstin": null
      },
      "total": "248000.00",
      "gst_breakdown": {
        "taxable_value": "221428.57",
        "cgst": "13285.71",
        "sgst": "13285.72",
        "igst": "0.00"
      }
    },
    {
      "id": "01HF8Y2A0B9C8D7E6F5G4H3J2K",
      "number": "INV-2026-0183",
      "status": "paid",
      "issued_at": "2026-06-08T16:45:51+05:30",
      "customer": {
        "id": "01HF8Y0Z1Y2X3W4V5U6T7S8R9Q",
        "name": "Sunrise Textiles Pvt Ltd",
        "gstin": "24AABCS1429B1Z6"
      },
      "total": "1062000.00",
      "gst_breakdown": {
        "taxable_value": "948214.29",
        "cgst": "0.00",
        "sgst": "0.00",
        "igst": "113785.71"
      }
    }
  ],
  "links": {
    "first": "https://api.evsuryam.com/v1/invoices?page=1",
    "prev": null,
    "next": "https://api.evsuryam.com/v1/invoices?page=2",
    "last": "https://api.evsuryam.com/v1/invoices?page=46"
  },
  "meta": {
    "current_page": 1,
    "per_page": 2,
    "last_page": 46,
    "total": 91
  }
}

Notice the second invoice carries igst (an inter-state sale to a registered GSTIN) while the first uses cgst + sgst (intra-state). evSuryam computes the split for you — see GST & compliance for the rules.

Webhook subscriptions

Polling the API for changes is wasteful. Instead, subscribe to webhooks and evSuryam will POST a JSON event to your endpoint the instant something happens — no cron job, no missed updates.

Create a subscription under Settings → API → Webhooks: enter the HTTPS URL that will receive events and tick the event types you care about. The most-used events:

EventFires when
invoice.paidAn invoice is fully settled — push it to your ledger.
invoice.createdA new invoice is issued.
installation.stage_completedAn install pipeline stage (survey, mounting, commissioning) is marked done.
inventory.low_stockAn item drops below its reorder threshold.

Every delivery is signed with an HMAC in the X-evSuryam-Signature header so you can verify it genuinely came from evSuryam, and each carries a unique event id for idempotency. The dedicated guide walks through the full payload, signature verification, and retry behaviour:

Sending invoice events to your accounting system →

Tally & Zoho Books sync

Most Indian solar vendors keep their books in Tally or Zoho Books. evSuryam pushes sales and purchase ledgers into both so your accountant never re-keys an invoice.

Sync can run on a schedule (nightly) or be triggered in real time off the invoice.paid webhook. Reverse-charge purchases — common on imported inverters — are tagged so the RCM liability lands in the right ledger; see reverse-charge on imported inverters.

Start with exportsIf you are not ready to wire up live API sync, the pre-built Tally XML and Zoho CSV exports under Settings → API → Accounting get you 90% of the value with zero code — download, import, done.

Next steps

You now have the lay of the land: base URL, tokens, resources, webhooks, and accounting sync. The natural next step is wiring real-time invoice events into your ledger — start with the focused invoice events guide. If you are still setting up your workspace, the getting started guide covers the prerequisites.

← Back to all resources

Ready to commission more, chase less?

14-day free trial. No credit card. Set up in under 10 minutes.

See plans Start free trial