Developers

Salesnix API

Drive Salesnix from your own systems over plain HTTPS: tell it to call a retailer, queue a whole list from a sheet, and pull back the outcome, the order it booked, and the full conversation transcript. REST endpoints, JSON in and out — no SDK required.

There are two API sets — jump to the one that fits you:

Base URLhttps://be.salesnix.com

Quickstart (sandbox)

Five requests, in order, with the sandbox key we send you. Nothing here places a real call — every response is realistic dummy data flagged "sandbox": true.

# Set your key once (we send it to you privately)
export KEY="sk_test_xxxxxxxxxxxxxxxx"
export B="https://be.salesnix.com"

# 1) Verify the key  → 200 with your client and env:"test"
curl -H "Authorization: Bearer $KEY" $B/api/me

# 2) Place a call  (clientId is optional — inferred from your key)
curl -X POST $B/api/calls/trigger -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone":"+919812345678","contactName":"Gupta Stores"}'
# → {"callId":900001,"status":"ringing","sandbox":true}

# 3) List calls  (no filter → both sample calls: 900001 + 900002)
curl -H "Authorization: Bearer $KEY" "$B/api/calls"

# 4) Read one call's full result (outcome + order + transcript)
curl -H "Authorization: Bearer $KEY" $B/api/calls/900001

When you're ready for production, swap the sandbox key for your live key (sk_live_…) — same requests, real calls and real data.

Authentication

Every endpoint requires a Salesnix API key. We issue you one key per environment — sk_live_… for production and sk_test_… for sandbox — bound to your client. Send it on every request as a bearer token:

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxx

An X-API-Key: sk_live_… header works too. Your key is scoped to your own client, so you only ever touch your own data; the clientId field is optional and, if sent, must match your own. Verify a key any time with GET /api/me.

Keep keys server-side. Rotate by asking us to issue a new one and revoke the old — revocation is instant. Need a key? Talk to us.

Sandbox vs. live

A sk_test_… key runs entirely in a sandbox: it places no real calls, writes nothing, and reads no real data. Every endpoint returns deterministic fixtures shaped exactly like live responses, with "sandbox": true on the payload — so you can build and verify the whole flow (place a call → poll → read the order & transcript) before going live.

  • POST /api/calls/trigger → returns call 900001 (no real dial).
  • GET /api/calls → two sample calls: 900001 (order booked) and 900002 (not connected).
  • GET /api/calls/900001 → a full booked-order result with line items and transcript.

When you're ready, swap the key for your sk_live_… one — same requests, real calls and real results. Nothing else changes.

What you can do

  • Repeat-order calling — push a retailer's number; the AI calls, references their history, takes a fresh order, and books it.
  • Bulk campaigns — upload a beat/territory sheet and queue a call to every retailer in one request.
  • Order capture — read back the exact order each call booked: SKUs, quantities, unit prices, and total value.
  • Outcome & CRM sync — pull per-call status (connected, order booked, not interested, follow-up) and duration into your own system.
  • Transcript & QA — fetch the full conversation transcript (and recording link, when enabled) for audit or analytics.
  • Reporting — list calls by status to build daily retailer-call and order-conversion reports.

For partners: run many companies from your own system

If you resell Salesnix to your own customers, you don't onboard them through our dashboard — you provision and fund them over the API. You get one partner key; everything you create belongs to you, and your customers never touch our platform.

  • One company = one API call. POST /api/partner/companies sets up the voice agent, stores that company's CRM login, and opens its billing account.
  • Billing rolls up to the company. Every call bills to that company's prepaid balance — never the individual retailer. You top companies up and pull per-company usage.
  • Retailers, products & history stay in your CRM. On each call the assistant identifies the retailer, reads their purchase history, and searches products live from your APIs using that company's credentials — nothing to pre-load.
  • Isolation. A partner key only ever sees its own companies; one company's data is never visible to another.

Add a company and fund it in three requests:

export PK="sk_live_your_partner_key"
export B="https://be.salesnix.com"

# 1) Create the company (returns a companyId)
curl -X POST $B/api/partner/companies -H "Authorization: Bearer $PK" \
  -H "Content-Type: application/json" -d '{
    "name":"Rasna",
    "integration":{"provider":"msell","baseUrl":"http://demo.msell.in/public/api",
      "auth":{"email":"12345@rasna","password":"••••••"}}}'
# → {"companyId":"msell-rasna","status":"active", ...}

# 2) Fund it (1 credit = ₹1)
curl -X POST $B/api/partner/companies/msell-rasna/credits \
  -H "Authorization: Bearer $PK" -H "Content-Type: application/json" -d '{"amount":5000}'

# 3) Check balance & usage any time
curl -H "Authorization: Bearer $PK" $B/api/partner/companies/msell-rasna/usage

Need a partner key? Talk to us— we issue it once and it's scoped to your account.

For a single company

Single-company API

For one brand or distributor running on their own Salesnix account. Authenticate with your per-company API key, trigger AI calls, and pull back outcomes, orders, and transcripts. If you resell Salesnix to many customers, use the Multi-tenant / Partner API below instead.

Authentication

Verify your API key and see the client it's bound to. Call this first.

GET/api/meAPI key

Verify credentials

Returns the identity behind your key — the client it's scoped to, its environment (live or sandbox), and granted scopes. A 200 here means your key is valid and you're ready to use the rest of the API.

Request
curl -H "Authorization: Bearer $SALESNIX_KEY" https://be.salesnix.com/api/me
# or:  curl -H "X-API-Key: $SALESNIX_KEY" https://be.salesnix.com/api/me
Response
{
  "authenticated": true,
  "kind": "apikey",
  "clientId": "dabur",
  "clientName": "Dabur",
  "scopes": ["calls:write", "calls:read"],
  "env": "test"
}

Place calls

Tell the AI agent to call a retailer and take the order — one number, or a whole list from a sheet. Returns immediately with a callId; the call runs asynchronously.

POST/api/calls/triggerAPI key

Call one retailer

Queues an AI voice call to one number and returns a callId right away. If the number must grant call permission first, Salesnix handles that and dials automatically once allowed. Poll GET /api/calls/{callId} for the outcome and order.

FieldTypeRequiredDescription
phonestringrequiredDestination number in E.164, e.g. +9198xxxxxxxx
clientIdstringOptional — defaults to the client your key is bound to
contactNamestringOptional retailer name for the record
Request
curl -X POST https://be.salesnix.com/api/calls/trigger \
  -H "Authorization: Bearer $SALESNIX_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone": "+919812345678", "contactName": "Gupta Stores" }'
Response
{
  "callId": 900001,
  "status": "ringing",
  "sandbox": true
}
POST/api/calls/uploadAPI key

Bulk-dial from a sheet

Upload a .csv or .xlsx of (name, phone) rows; Salesnix queues one AI call per row (up to 200). Headers are auto-detected — name/contact/retailer and phone/mobile/number all work.

FieldTypeRequiredDescription
filefilerequiredmultipart/form-data .csv or .xlsx
clientIdstringOptional — defaults to the client your key is bound to
Request
curl -X POST https://be.salesnix.com/api/calls/upload \
  -H "Authorization: Bearer $SALESNIX_KEY" \
  -F "file=@retailers.xlsx"
Response
{
  "queued": 42,
  "callIds": [900001, 900002, "…"],
  "sandbox": true
}

Read results

Pull back everything that happened on a call — outcome, duration, the order it booked (line items + total), and the full transcript.

GET/api/callsAPI key

List calls

Your client's calls, newest first. Optionally filter with ?status=completed|missed|failed|ringing and ?limit=N (max 200). In sandbox you'll always see two: 900001 (completed/order booked) and 900002 (missed/not connected) — add ?status=completed to see only the first.

Request
curl -H "Authorization: Bearer $SALESNIX_KEY" \
  "https://be.salesnix.com/api/calls?limit=20"
Response
[
  {
    "callId": 900001,
    "status": "completed",
    "outcome": "order_booked",
    "durationSecs": 138,
    "contactName": "Gupta Stores",
    "phone": "+919812345678",
    "startedAt": "2026-06-16T11:04:00+05:30",
    "summary": "Repeat order confirmed; accepted Butter Cookies upsell.",
    "orderId": 500001,
    "orderTotal": 4250,
    "sandbox": true
  },
  {
    "callId": 900002,
    "status": "missed",
    "outcome": "not_connected",
    "durationSecs": 0,
    "contactName": "Sharma Kirana",
    "phone": "+919800000002",
    "startedAt": "2026-06-16T11:09:00+05:30",
    "summary": "Retailer did not pick up. Follow-up required.",
    "orderId": null,
    "orderTotal": null,
    "sandbox": true
  }
]
GET/api/calls/{callId}API key

Get one call (outcome + order + transcript)

The complete record for a call: status, duration, the order placed (SKU, qty, unit price, line amount, total), the recording link when available, and the turn-by-turn transcript.

Request
curl -H "Authorization: Bearer $SALESNIX_KEY" \
  https://be.salesnix.com/api/calls/900001
Response
{
  "callId": 900001,
  "status": "completed",
  "outcome": "order_booked",
  "durationSecs": 138,
  "contactName": "Gupta Stores",
  "phone": "+919812345678",
  "startedAt": "2026-06-16T11:04:00+05:30",
  "summary": "Booked Chiji Noodles 15 box, Ringo Star 3 box …",
  "recordingUrl": "https://…/900001.mp3",
  "order": {
    "orderId": 500001,
    "status": "placed",
    "total": 4250,
    "items": [
      { "sku": "CHIJI-5", "name": "Chiji Noodles Rs 5",
        "qty": 15, "unitPrice": 5, "amount": 75 }
    ]
  },
  "transcript": [
    { "role": "ai", "text": "Namaste Gupta Ji…", "atSecs": 0 },
    { "role": "customer", "text": "Haan ji boliye.", "atSecs": 4 }
  ],
  "sandbox": true
}
For multi-tenant partners

Multi-tenant / Partner API

For partners who resell Salesnix to their own customers. One partner key provisions and funds many companies, builds each company's voice agent, and reads calls across all of them — entirely over the API, no dashboard. Everything you create is scoped to you; you never see another partner's data.

Partner — provision companies

For platform partners who resell Salesnix to their own customers. With a partner key you create and fund a company (a tenant) entirely over the API — no dashboard. Each company is billed separately; usage rolls up to the company, never the individual caller.

POST/api/partner/companiesPartner key

Create a company

Provisions a company in one call: its voice agent, its CRM credentials (so the assistant can reach that company's retailers, products and history), and its prepaid billing account. Returns a companyId you use for every later call.

FieldTypeRequiredDescription
namestringrequiredDisplay name of the company, e.g. "Rasna"
companyIdstringOptional explicit slug; otherwise derived from the name and namespaced to you
integrationobjectrequiredThe company's external-CRM login: { provider, baseUrl, auth }. auth holds the provider's credentials (for mSELL: email + password).
Request
curl -X POST https://be.salesnix.com/api/partner/companies \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Rasna",
    "integration": {
      "provider": "msell",
      "baseUrl": "http://demo.msell.in/public/api",
      "auth": { "email": "12345@rasna", "password": "••••••" }
    }
  }'
Response
{
  "companyId": "msell-rasna",
  "name": "Rasna",
  "status": "active",
  "partnerId": "msell",
  "integration": {
    "provider": "msell",
    "baseUrl": "http://demo.msell.in/public/api"
  }
}
GET/api/partner/companiesPartner key

List your companies

Every company you've provisioned, newest name first. You only ever see your own — a partner key can never touch another partner's tenants.

Request
curl -H "Authorization: Bearer $PARTNER_KEY" \
  https://be.salesnix.com/api/partner/companies
Response
[
  { "companyId": "msell-rasna", "name": "Rasna", "status": "active", "partnerId": "msell" }
]
PATCH/api/partner/companies/{companyId}Partner key

Update a company

Change a company's display name or rotate its CRM credentials. Send only the fields you want to change.

Request
curl -X PATCH https://be.salesnix.com/api/partner/companies/msell-rasna \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "integration": { "auth": { "email": "12345@rasna", "password": "new-secret" } } }'
Response
{ "companyId": "msell-rasna", "name": "Rasna", "status": "active",
  "integration": { "provider": "msell", "baseUrl": "http://demo.msell.in/public/api" } }
POST/api/partner/companies/{companyId}/creditsPartner key

Top up a company

Add prepaid credits to a company's balance (1 credit = ₹1). You fund each company; all of that company's call usage draws down its own balance.

FieldTypeRequiredDescription
amountnumberrequiredAmount in INR to credit, e.g. 5000
Request
curl -X POST https://be.salesnix.com/api/partner/companies/msell-rasna/credits \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 5000 }'
Response
{ "clientId": "msell-rasna", "added": 5000, "balance": 5000, "gateway": "partner" }
GET/api/partner/companies/{companyId}/usagePartner key

Company balance & usage

The company's current prepaid balance and its recent ledger (top-ups and per-call charges) — build per-company statements from this.

Request
curl -H "Authorization: Bearer $PARTNER_KEY" \
  https://be.salesnix.com/api/partner/companies/msell-rasna/usage
Response
{
  "companyId": "msell-rasna",
  "balance": 4830.5,
  "lowBalance": 100,
  "currency": "credit",
  "ledger": [
    { "delta": 5000, "kind": "recharge", "reason": "recharge via partner by msell", "balanceAfter": 5000 },
    { "delta": -169.5, "kind": "call", "reason": "138s @ 4/min", "balanceAfter": 4830.5 }
  ]
}

Partner — wallet & allocation

Fund one shared partner wallet, then push credits down to each company. Company calls always bill from that company's own balance; the wallet is just your funding pool. Auto-refill tops a company up from the wallet when it runs low.

GET/api/partner/walletPartner key

Wallet balance & ledger

Your shared wallet's current balance and its recent movements (recharges in, allocations out).

Request
curl -H "Authorization: Bearer $PARTNER_KEY" https://be.salesnix.com/api/partner/wallet
Response
{
  "partnerId": "msell",
  "balance": 42000,
  "lowBalance": 1000,
  "currency": "credit",
  "ledger": [
    { "delta": 50000, "kind": "recharge", "reason": "recharge via razorpay", "balanceAfter": 50000 },
    { "delta": -8000, "kind": "allocation", "reason": "allocate to msell-rasna", "balanceAfter": 42000 }
  ]
}
POST/api/partner/wallet/rechargePartner key

Recharge the wallet

Start a wallet top-up (min ₹1,000). When Razorpay is enabled you get an order to pay (GST + gateway fee added on top; the wallet is credited the base amount), then confirm it via /wallet/recharge/verify. Without a gateway it returns a manual intent an admin confirms.

FieldTypeRequiredDescription
amountInrnumberrequiredCredits to add to the wallet (1 credit = ₹1), min 1000
Request
curl -X POST https://be.salesnix.com/api/partner/wallet/recharge \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amountInr": 50000 }'
Response
{
  "paymentId": 812, "amountInr": 50000, "credits": 50000,
  "gateway": "razorpay", "status": "pending",
  "razorpayOrderId": "order_Nx…", "razorpayKeyId": "rzp_live_…"
}
POST/api/partner/companies/{companyId}/allocatePartner key

Allocate wallet → company

Atomically move credits from your wallet into a company's balance. Refuses if the wallet is underfunded.

FieldTypeRequiredDescription
amountnumberrequiredCredits to move from the wallet to this company
Request
curl -X POST https://be.salesnix.com/api/partner/companies/msell-rasna/allocate \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 8000 }'
Response
{ "companyId": "msell-rasna", "companyBalance": 8000, "wallet": 42000 }
POST/api/partner/companies/{companyId}/auto-refillPartner key

Set company auto-refill

When this company's balance dips below its low-balance threshold, pull this many credits from your wallet automatically. Set 0 to turn it off.

FieldTypeRequiredDescription
amountnumberrequiredAuto-refill amount in credits (0 disables)
Request
curl -X POST https://be.salesnix.com/api/partner/companies/msell-rasna/auto-refill \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 2000 }'
Response
{ "companyId": "msell-rasna", "autoRefill": 2000 }

Partner — agents & tools

Build and manage each company's voice agent (persona, greeting, and which tools it can call) programmatically — the same thing the partner dashboard does. The tool catalog is scoped per company, so it sees its own CRM tools but never another client's.

GET/api/partner/companies/{companyId}/toolsPartner key

Tool catalog + voices

The tools this company's agent may be granted (CRM tools if it has an integration) plus the available voices, for building an agent.

Request
curl -H "Authorization: Bearer $PARTNER_KEY" \
  https://be.salesnix.com/api/partner/companies/msell-rasna/tools
Response
{
  "tools": [
    { "name": "identify_customer", "label": "Identify caller", "group": "Retail CRM", "kind": "crm" },
    { "name": "get_purchase_history", "label": "Purchase history", "group": "Retail CRM", "kind": "crm" },
    { "name": "search_products", "label": "Search products", "group": "Retail CRM", "kind": "crm" },
    { "name": "connect_to_support", "label": "Connect to support", "group": "Retail CRM", "kind": "crm" }
  ],
  "voices": ["Aoede", "Charon", "…"]
}
GET/api/partner/companies/{companyId}/agentsPartner key

List a company's agents

The voice agents belonging to this company (not shared/global demo agents).

Request
curl -H "Authorization: Bearer $PARTNER_KEY" \
  https://be.salesnix.com/api/partner/companies/msell-rasna/agents
Response
[
  { "id": 42, "name": "mSELL Voice Assistant", "voice": "Charon",
    "tools": ["identify_customer","get_purchase_history","search_products","connect_to_support"] }
]
POST/api/partner/companies/{companyId}/agentsPartner key

Create an agent

Create a voice agent for a company: its name, voice, greeting, system prompt, and the tools it may call. (PUT …/agents/{agentId} updates it, DELETE removes it.)

FieldTypeRequiredDescription
namestringrequiredAgent name
voicestringVoice id (default Aoede)
greetingstringOpening line
promptstringSystem prompt
toolsstring[]Tool names from the company's catalog
Request
curl -X POST https://be.salesnix.com/api/partner/companies/msell-rasna/agents \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "mSELL Voice Assistant", "voice": "Charon",
    "greeting": "Namaste! …",
    "prompt": "You are the mSELL voice assistant …",
    "tools": ["identify_customer","get_purchase_history","search_products","connect_to_support"]
  }'
Response
{ "id": 42, "name": "mSELL Voice Assistant", "voice": "Charon", "tools": ["…"] }
POST/api/partner/companies/{companyId}/tools/{toolName}/testPartner key

Test a tool

Fire one CRM/n8n tool directly (no live call) to confirm the webhook is wired for a company before a demo.

Request
curl -X POST https://be.salesnix.com/api/partner/companies/msell-rasna/tools/search_products/test \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "args": { "query": "mango" } }'
Response
{ "tool": "search_products", "ok": true, "result": { "count": 1, "products": [ "…" ] } }

Partner — call logs & keys

Read call activity across all your companies, confirm your identity, and mint your own API keys for server-to-server use.

GET/api/partner/callsPartner key

Calls across your companies

Every call across your companies (or filter to one with ?company_id=), newest first — for a log table or CSV export. Includes per-call cost.

FieldTypeRequiredDescription
company_idstringOptional — restrict to one company
limitnumberMax rows (default 500, max 2000)
Request
curl -H "Authorization: Bearer $PARTNER_KEY" \
  "https://be.salesnix.com/api/partner/calls?limit=100"
Response
[
  {
    "id": 90210, "companyId": "msell-rasna", "companyName": "Rasna",
    "contactName": "Gupta Stores", "phone": "+9199…", "direction": "inbound",
    "status": "completed", "outcomeKey": "answered",
    "startedAt": "2026-07-11T11:04:00+05:30", "durationSecs": 138, "cost": 9.2
  }
]
GET/api/partner/mePartner key

Who am I

Confirms your partner identity behind the key or login. Call this first to verify credentials.

Request
curl -H "Authorization: Bearer $PARTNER_KEY" https://be.salesnix.com/api/partner/me
Response
{ "partnerId": "msell", "name": "mSELL", "kind": "apikey" }
POST/api/partner/keysPartner key

Mint an API key

Create a partner API key for server-to-server use — same permissions as your dashboard login. The plaintext key is returned ONCE. (GET lists your keys; DELETE …/keys/{keyId} revokes one instantly.)

FieldTypeRequiredDescription
namestringA label, e.g. "Production"
envstring"live" or "test" (default live)
Request
curl -X POST https://be.salesnix.com/api/partner/keys \
  -H "Authorization: Bearer $PARTNER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Production", "env": "live" }'
Response
{
  "id": "…", "partnerId": "msell", "name": "Production", "env": "live",
  "keyPrefix": "sk_live_ab12", "scopes": ["companies:write","companies:read"],
  "key": "sk_live_ab12…copy-this-now"
}
General

General

Status

GET/healthPublic

Health check

Liveness probe for uptime monitoring. No auth.

Response
{ "status": "ok" }

Ready to integrate?

Get your credentials and a sandbox client set up.

Get API access