Skip to content

Documentation

Getting started

The Easarc API is a JSON over HTTPS API. If you can send a request with a bearer token, you already know how to use it. Everything is served from ap-south-1 (Mumbai).

Base URLs and environments

Every account has two environments. They are completely separate: separate data, separate keys, separate webhooks. A sandbox key will never touch production data, which is the point.

API base URLs by environment
EnvironmentBase URLKey prefix
Productionhttps://api.easarctech.com/v1esk_live_
Sandboxhttps://api.sandbox.easarctech.com/v1esk_test_

Sandbox behaves identically to production, except that GST e-invoice and e-way bill calls hit the government sandbox rather than the live IRP, and WhatsApp messages are recorded instead of sent.

Your first request

Create an API key in the dashboard under Settings → API keys, then list two orders. The Easarc-Version header pins the API version — see the changelog for what versions exist and what changed in each.

curl
curl https://api.easarctech.com/v1/orders?limit=2 \
  -H "Authorization: Bearer esk_live_7f3a9c2e8b14d05a" \
  -H "Easarc-Version: 2026-08-01"
JavaScript
const response = await fetch(
  'https://api.easarctech.com/v1/orders?limit=2',
  {
    headers: {
      Authorization: `Bearer ${process.env.EASARC_API_KEY}`,
      'Easarc-Version': '2026-08-01',
    },
  }
)

if (!response.ok) {
  const { error } = await response.json()
  throw new Error(`${error.code}: ${error.message}`)
}

const { data, has_more, next_cursor } = await response.json()
console.log(data.length, has_more, next_cursor)

The response

List endpoints return a data array with has_more and next_cursor alongside it. Single-object endpoints return the object at the top level, without a wrapper.

200 OK
{
  "data": [
    {
      "id": "ord_01J9ZK4M7Q2X8V",
      "reference": "ESR-2026-0431",
      "buyer": { "id": "buy_01J8T2A5", "name": "Rajhans Exports" },
      "unit_id": "unt_02",
      "status": "in_production",
      "stage": "printing",
      "quantity": { "value": 4800, "uom": "MTR" },
      "value": { "amount": 74240000, "currency": "INR" },
      "ordered_on": "2026-07-12",
      "due_on": "2026-08-02",
      "created_at": "2026-07-12T09:14:22+05:30"
    },
    {
      "id": "ord_01J9ZK51PD8W3M",
      "reference": "ESR-2026-0434",
      "buyer": { "id": "buy_01J8T3B9", "name": "Meghdoot Fabrics" },
      "unit_id": "unt_01",
      "status": "ready_to_dispatch",
      "stage": "packing",
      "quantity": { "value": 1200, "uom": "PCS" },
      "value": { "amount": 81600000, "currency": "INR" },
      "ordered_on": "2026-07-18",
      "due_on": "2026-08-06",
      "created_at": "2026-07-18T11:02:47+05:30"
    }
  ],
  "has_more": true,
  "next_cursor": "ord_01J9ZK51PD8W3M"
}

Conventions

  • Money is in paise. An amount of 74240000 with currency INR is ₹7,42,400. We never send floats for money.
  • Dates are ISO 8601. Calendar dates as 2026-08-02; timestamps with an offset, and the offset is +05:30 unless you ask for UTC with Easarc-Timezone: UTC.
  • Identifiers are prefixed and opaque. ord_, buy_, cam_, evt_. Do not parse them. Your own referenceESR-2026-0431 — is a separate field you control.
  • Enums are lower_snake_case and we only ever add values, never rename them within an API version.
  • Units of measure use UQC codes MTR, PCS, KGS — the same codes the GST portal expects.
  • Unknown fields in a request are rejected, not ignored. A typo in a field name is an error, not a silent no-op.

Pagination

List endpoints are cursor-paginated. Pass limit (1–100, default 25) and cursor. Keep requesting while has_more is true, passing the previous next_cursor. Cursors are stable across inserts, so you will not see an item twice or skip one because something was created mid-walk.

Walking every page
let cursor
const all = []

do {
  const url = new URL('https://api.easarctech.com/v1/orders')
  url.searchParams.set('limit', '100')
  if (cursor) url.searchParams.set('cursor', cursor)

  const page = await fetch(url, { headers }).then((r) => r.json())
  all.push(...page.data)
  cursor = page.has_more ? page.next_cursor : undefined
} while (cursor)

Idempotency

Every POST accepts an Idempotency-Key header. Send a UUID you generate. If the same key arrives twice within 24 hours we return the original response rather than creating a second order — which matters when a request times out and you do not know whether it landed.

curl
curl -X POST https://api.easarctech.com/v1/orders \
  -H "Authorization: Bearer esk_live_7f3a9c2e8b14d05a" \
  -H "Easarc-Version: 2026-08-01" \
  -H "Idempotency-Key: 8f14e45f-ceea-467a-9f0c-1b2d3e4f5a6b" \
  -H "Content-Type: application/json" \
  -d '{ "reference": "ESR-2026-0431", "buyer_id": "buy_01J8T2A5" }'

SDKs

The SDKs handle authentication, retries with backoff, cursor pagination and webhook signature verification. You do not need them — the API is plain HTTP — but they remove the parts everyone gets wrong.

Install
# JavaScript and TypeScript
npm install @easarc/sdk

# Python
pip install easarc

# CLI, for Easarc Deploy
npm install -g @easarc/cli

Where to go next