Leads & Pipeline

Beta

Leads (enquiries before they are customers) and opportunities (deals moving through stages to Won or Lost). Values are in the base currency. A SALES member whose organization limits them to their own deals sees only those; anything else is a 404. Quotes, sales orders and invoices take an optional opportunityId and move the deal forward as they progress.

GET/api/v1/leads

List leads

Scope: crm.read

Parameters

NameInTypeRequiredDescription
statusquerystringOptionalComma-separated: NEW, CONTACTED, QUALIFIED, CONVERTED, DISQUALIFIED.
sourcequerystringOptionalComma-separated sources (WHATSAPP, CALL, WALK_IN, TRADE_SHOW, REFERRAL, WEBSITE, OTHER).
ownerUserIdquerystringOptionalOwner's user ID.
minequerybooleanOptionalOnly leads you own.
followUpDuequerybooleanOptionalFollow-up due today or earlier.
qquerystringOptionalName, company, email or phone.
pagequerynumberOptional1-based page number.
limitquerynumberOptionalPage size, max 200.

Example request

curl "https://invoice.avscorp.in/api/v1/leads" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "id": "clx7led00000000000000001",
  "name": "Ravi Kumar",
  "companyName": "Ravi Textiles",
  "phone": "98765 43210",
  "phoneKey": "9876543210",
  "email": "ravi@example.com",
  "source": "WHATSAPP",
  "sourceDetail": null,
  "requirement": "200 cotton shirts, delivery by March",
  "estimatedValue": 80000,
  "status": "QUALIFIED",
  "disqualifyReason": null,
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "convertedCustomerId": null,
  "convertedCustomerName": null,
  "convertedAt": null,
  "whatsappPhone": "919876543210",
  "gstin": null,
  "stateCode": "TN",
  "city": "Tiruppur",
  "opportunities": [],
  "createdAt": "2026-10-27T09:00:00.000Z",
  "updatedAt": "2026-10-27T09:00:00.000Z"
}

Possible errors: unauthorized, insufficient_scope, forbidden, validation_error

POST/api/v1/leads

Create a lead

Scope: crm.create

A phone whose last 10 digits match an open lead or a customer returns 409 conflict with error.details.duplicates ([{ kind: LEAD|CUSTOMER, id, name, phone, status? }]). Send allowDuplicate: true to save it anyway. The owner defaults to you.

Request body

FieldTypeRequiredConstraints
namestringRequiredmin length 1; max length 191
companyNameanyOptional—
phoneanyOptional—
emailanyOptional—
sourcestringOptionalone of: WHATSAPP, CALL, WALK_IN, TRADE_SHOW, REFERRAL, WEBSITE, PORTAL, OTHER; default "OTHER"
sourceDetailanyOptional—
requirementanyOptional—
estimatedValueanyOptional—
ownerUserIdanyOptional—
nextFollowUpAtanyOptional—
whatsappPhoneanyOptional—
gstinanyOptional—
stateCodeanyOptional—
cityanyOptional—
allowDuplicatebooleanOptional—

Example request

curl -X POST "https://invoice.avscorp.in/api/v1/leads" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Ravi Kumar",
  "companyName": "Ravi Textiles",
  "phone": "98765 43210",
  "source": "WHATSAPP",
  "requirement": "200 cotton shirts",
  "estimatedValue": 80000
}'

Example response

JSON
{
  "id": "clx7led00000000000000001",
  "name": "Ravi Kumar",
  "companyName": "Ravi Textiles",
  "phone": "98765 43210",
  "phoneKey": "9876543210",
  "email": "ravi@example.com",
  "source": "WHATSAPP",
  "sourceDetail": null,
  "requirement": "200 cotton shirts, delivery by March",
  "estimatedValue": 80000,
  "status": "NEW",
  "disqualifyReason": null,
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "convertedCustomerId": null,
  "convertedCustomerName": null,
  "convertedAt": null,
  "whatsappPhone": "919876543210",
  "gstin": null,
  "stateCode": "TN",
  "city": "Tiruppur",
  "opportunities": [],
  "createdAt": "2026-10-27T09:00:00.000Z",
  "updatedAt": "2026-10-27T09:00:00.000Z"
}

Possible errors: unauthorized, insufficient_scope, forbidden, conflict, validation_error

GET/api/v1/leads/{id}

Get a lead

Scope: crm.read

Parameters

NameInTypeRequiredDescription
idpathstringRequiredLead ID.

Example request

curl "https://invoice.avscorp.in/api/v1/leads/clx7led00000000000000001" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "id": "clx7led00000000000000001",
  "name": "Ravi Kumar",
  "companyName": "Ravi Textiles",
  "phone": "98765 43210",
  "phoneKey": "9876543210",
  "email": "ravi@example.com",
  "source": "WHATSAPP",
  "sourceDetail": null,
  "requirement": "200 cotton shirts, delivery by March",
  "estimatedValue": 80000,
  "status": "QUALIFIED",
  "disqualifyReason": null,
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "convertedCustomerId": null,
  "convertedCustomerName": null,
  "convertedAt": null,
  "whatsappPhone": "919876543210",
  "gstin": null,
  "stateCode": "TN",
  "city": "Tiruppur",
  "opportunities": [],
  "createdAt": "2026-10-27T09:00:00.000Z",
  "updatedAt": "2026-10-27T09:00:00.000Z"
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found

PATCH/api/v1/leads/{id}

Update a lead

Scope: crm.update

Send only the fields to change. status changes it (NEW, CONTACTED, QUALIFIED, or DISQUALIFIED with disqualifyReason); conversion has its own endpoint. A converted lead can't be edited.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredLead ID.

Example request

curl -X PATCH "https://invoice.avscorp.in/api/v1/leads/clx7led00000000000000001" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "QUALIFIED",
  "nextFollowUpAt": "2026-10-30"
}'

Example response

JSON
{
  "id": "clx7led00000000000000001",
  "name": "Ravi Kumar",
  "companyName": "Ravi Textiles",
  "phone": "98765 43210",
  "phoneKey": "9876543210",
  "email": "ravi@example.com",
  "source": "WHATSAPP",
  "sourceDetail": null,
  "requirement": "200 cotton shirts, delivery by March",
  "estimatedValue": 80000,
  "status": "QUALIFIED",
  "disqualifyReason": null,
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "convertedCustomerId": null,
  "convertedCustomerName": null,
  "convertedAt": null,
  "whatsappPhone": "919876543210",
  "gstin": null,
  "stateCode": "TN",
  "city": "Tiruppur",
  "opportunities": [],
  "createdAt": "2026-10-27T09:00:00.000Z",
  "updatedAt": "2026-10-27T09:00:00.000Z"
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found, conflict, validation_error

DELETE/api/v1/leads/{id}

Delete a lead

Scope: crm.delete

Refused (422) once converted or while it has opportunities; disqualify it instead.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredLead ID.

Example request

curl -X DELETE "https://invoice.avscorp.in/api/v1/leads/clx7led00000000000000001" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "deleted": true
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found, validation_error

POST/api/v1/leads/{id}/convert

Convert a lead to a customer

Scope: crm.update

mode new creates the customer (also needs the customers.create scope and role permission, and counts toward the plan's customer limit); mode existing links one. Open opportunities move to the customer; createOpportunity (default true) adds one from the requirement when there is none. Converting again returns the same customer with alreadyConverted: true.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredLead ID.

Request body

FieldTypeRequiredConstraints

Example request

curl -X POST "https://invoice.avscorp.in/api/v1/leads/clx7led00000000000000001/convert" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mode": "new",
  "customer": {
    "displayName": "Ravi Textiles",
    "phone": "98765 43210"
  },
  "createOpportunity": true
}'

Example response

JSON
{
  "customerId": "clx1cus000000000000000001",
  "opportunityId": "clx8opp00000000000000001",
  "alreadyConverted": false
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found, validation_error

GET/api/v1/opportunities

List opportunities

Scope: crm.read

Parameters

NameInTypeRequiredDescription
statusquerystringOptionalComma-separated: OPEN, WON, LOST.
stageIdquerystringOptionalComma-separated stage IDs.
ownerUserIdquerystringOptionalOwner's user ID.
salespersonIdquerystringOptionalSalesperson ID.
minequerybooleanOptionalOnly deals you own.
closeFromquerystringOptionalExpected close on or after (YYYY-MM-DD).
closeToquerystringOptionalExpected close on or before (YYYY-MM-DD).
followUpDuequerybooleanOptionalFollow-up due today or earlier.
qquerystringOptionalTitle, customer or lead name.
sortquerystringOptionalexpectedCloseDate, expectedValue, createdAt (default) or title.
dirquerystringOptionalasc or desc (default).
pagequerynumberOptional1-based page number.
limitquerynumberOptionalPage size, max 200.

Example request

curl "https://invoice.avscorp.in/api/v1/opportunities" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "id": "clx8opp00000000000000001",
  "title": "200 cotton shirts",
  "leadId": "clx7led00000000000000001",
  "customerId": "clx1cus000000000000000001",
  "stageId": "clx8stg00000000000000003",
  "stageName": "Proposal",
  "partyName": "Ravi Textiles",
  "status": "OPEN",
  "expectedValue": 80000,
  "wonValue": null,
  "probability": 50,
  "probabilityOverridden": false,
  "expectedCloseDate": "2026-11-15T00:00:00.000Z",
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "salespersonId": null,
  "salespersonName": null,
  "source": "WHATSAPP",
  "lostReasonId": null,
  "lostReasonName": null,
  "lostNote": null,
  "closedAt": null,
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "latestQuoteNumber": "QT-00042"
}

Possible errors: unauthorized, insufficient_scope, forbidden, validation_error

POST/api/v1/opportunities

Create an opportunity

Scope: crm.create

On a leadId, a customerId, or both. stageId defaults to the first open stage; probability defaults to the stage's.

Request body

FieldTypeRequiredConstraints
titlestringRequiredmin length 1; max length 191
leadIdanyOptional—
customerIdanyOptional—
stageIdanyOptional—
expectedValuenumberOptionalmin 0; max 10000000000000; default 0
expectedCloseDateanyOptional—
probabilityanyOptional—
ownerUserIdanyOptional—
salespersonIdanyOptional—
nextFollowUpAtanyOptional—

Example request

curl -X POST "https://invoice.avscorp.in/api/v1/opportunities" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "200 cotton shirts",
  "customerId": "clx1cus000000000000000001",
  "expectedValue": 80000,
  "expectedCloseDate": "2026-11-15"
}'

Example response

JSON
{
  "id": "clx8opp00000000000000001",
  "title": "200 cotton shirts",
  "leadId": "clx7led00000000000000001",
  "customerId": "clx1cus000000000000000001",
  "stageId": "clx8stg00000000000000003",
  "stageName": "New",
  "partyName": "Ravi Textiles",
  "status": "OPEN",
  "expectedValue": 80000,
  "wonValue": null,
  "probability": 10,
  "probabilityOverridden": false,
  "expectedCloseDate": "2026-11-15T00:00:00.000Z",
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "salespersonId": null,
  "salespersonName": null,
  "source": "WHATSAPP",
  "lostReasonId": null,
  "lostReasonName": null,
  "lostNote": null,
  "closedAt": null,
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "history": [],
  "documents": []
}

Possible errors: unauthorized, insufficient_scope, forbidden, validation_error

GET/api/v1/opportunities/{id}

Get an opportunity

Scope: crm.read

With its stage history and the quotes, sales orders and invoices linked to it.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredOpportunity ID.

Example request

curl "https://invoice.avscorp.in/api/v1/opportunities/clx8opp00000000000000001" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "id": "clx8opp00000000000000001",
  "title": "200 cotton shirts",
  "leadId": "clx7led00000000000000001",
  "customerId": "clx1cus000000000000000001",
  "stageId": "clx8stg00000000000000003",
  "stageName": "Proposal",
  "partyName": "Ravi Textiles",
  "status": "OPEN",
  "expectedValue": 80000,
  "wonValue": null,
  "probability": 50,
  "probabilityOverridden": false,
  "expectedCloseDate": "2026-11-15T00:00:00.000Z",
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "salespersonId": null,
  "salespersonName": null,
  "source": "WHATSAPP",
  "lostReasonId": null,
  "lostReasonName": null,
  "lostNote": null,
  "closedAt": null,
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "history": [
    {
      "id": "clx8hst00000000000000001",
      "fromStageName": "New",
      "toStageName": "Proposal",
      "toStatus": "OPEN",
      "source": "AUTO",
      "reason": "Quote QT-00042 sent",
      "changedByName": "Asha Rao",
      "changedAt": "2026-10-28T10:00:00.000Z"
    }
  ],
  "documents": [
    {
      "kind": "QUOTE",
      "id": "clx3quo000000000000000001",
      "number": "QT-00042",
      "status": "SENT",
      "total": 94400,
      "currencyCode": "INR",
      "date": "2026-10-28T00:00:00.000Z"
    }
  ]
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found

PATCH/api/v1/opportunities/{id}

Update an opportunity

Scope: crm.update

Send only the fields to change. The stage moves through POST /opportunities/{id}/stage. probability: null goes back to the stage's default.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredOpportunity ID.

Example request

curl -X PATCH "https://invoice.avscorp.in/api/v1/opportunities/clx8opp00000000000000001" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "expectedValue": 90000,
  "nextFollowUpAt": "2026-11-02"
}'

Example response

JSON
{
  "id": "clx8opp00000000000000001",
  "title": "200 cotton shirts",
  "leadId": "clx7led00000000000000001",
  "customerId": "clx1cus000000000000000001",
  "stageId": "clx8stg00000000000000003",
  "stageName": "Proposal",
  "partyName": "Ravi Textiles",
  "status": "OPEN",
  "expectedValue": 80000,
  "wonValue": null,
  "probability": 50,
  "probabilityOverridden": false,
  "expectedCloseDate": "2026-11-15T00:00:00.000Z",
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "salespersonId": null,
  "salespersonName": null,
  "source": "WHATSAPP",
  "lostReasonId": null,
  "lostReasonName": null,
  "lostNote": null,
  "closedAt": null,
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "history": [
    {
      "id": "clx8hst00000000000000001",
      "fromStageName": "New",
      "toStageName": "Proposal",
      "toStatus": "OPEN",
      "source": "AUTO",
      "reason": "Quote QT-00042 sent",
      "changedByName": "Asha Rao",
      "changedAt": "2026-10-28T10:00:00.000Z"
    }
  ],
  "documents": [
    {
      "kind": "QUOTE",
      "id": "clx3quo000000000000000001",
      "number": "QT-00042",
      "status": "SENT",
      "total": 94400,
      "currencyCode": "INR",
      "date": "2026-10-28T00:00:00.000Z"
    }
  ]
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found, validation_error

DELETE/api/v1/opportunities/{id}

Delete an opportunity

Scope: crm.delete

Linked quotes, orders and invoices stay; they lose the link.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredOpportunity ID.

Example request

curl -X DELETE "https://invoice.avscorp.in/api/v1/opportunities/clx8opp00000000000000001" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "deleted": true
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found

POST/api/v1/opportunities/{id}/stage

Move an opportunity to a stage

Scope: crm.update

Won takes wonValue (defaults to the expected value; must be above 0); Lost needs lostReasonId (and lostNote for the reason named Other). Moving a closed deal to an open stage reopens it. Archived stages are refused.

Parameters

NameInTypeRequiredDescription
idpathstringRequiredOpportunity ID.

Request body

FieldTypeRequiredConstraints
stageIdstringRequiredmin length 1; max length 30
wonValuenumber | nullOptional—
lostReasonIdanyOptional—
lostNoteanyOptional—

Example request

curl -X POST "https://invoice.avscorp.in/api/v1/opportunities/clx8opp00000000000000001/stage" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "stageId": "clx8stg00000000000000005",
  "wonValue": 78000
}'

Example response

JSON
{
  "id": "clx8opp00000000000000001",
  "title": "200 cotton shirts",
  "leadId": "clx7led00000000000000001",
  "customerId": "clx1cus000000000000000001",
  "stageId": "clx8stg00000000000000003",
  "stageName": "Won",
  "partyName": "Ravi Textiles",
  "status": "WON",
  "expectedValue": 80000,
  "wonValue": 78000,
  "probability": 100,
  "probabilityOverridden": false,
  "expectedCloseDate": "2026-11-15T00:00:00.000Z",
  "ownerUserId": "clxusr0000000000000000002",
  "ownerName": "Asha Rao",
  "salespersonId": null,
  "salespersonName": null,
  "source": "WHATSAPP",
  "lostReasonId": null,
  "lostReasonName": null,
  "lostNote": null,
  "closedAt": "2026-11-10T12:00:00.000Z",
  "nextFollowUpAt": "2026-10-30T00:00:00.000Z",
  "history": [
    {
      "id": "clx8hst00000000000000001",
      "fromStageName": "New",
      "toStageName": "Proposal",
      "toStatus": "OPEN",
      "source": "AUTO",
      "reason": "Quote QT-00042 sent",
      "changedByName": "Asha Rao",
      "changedAt": "2026-10-28T10:00:00.000Z"
    }
  ],
  "documents": [
    {
      "kind": "QUOTE",
      "id": "clx3quo000000000000000001",
      "number": "QT-00042",
      "status": "SENT",
      "total": 94400,
      "currencyCode": "INR",
      "date": "2026-10-28T00:00:00.000Z"
    }
  ]
}

Possible errors: unauthorized, insufficient_scope, forbidden, not_found, validation_error

GET/api/v1/opportunity-stages

List pipeline stages

Scope: crm.read

Example request

curl "https://invoice.avscorp.in/api/v1/opportunity-stages" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "id": "clx8stg00000000000000003",
  "name": "Proposal",
  "sortOrder": 2,
  "defaultProbability": 50,
  "systemKey": "PROPOSAL",
  "isWon": false,
  "isLost": false,
  "isArchived": false
}

Possible errors: unauthorized, insufficient_scope, forbidden

GET/api/v1/lost-reasons

List lost reasons

Scope: crm.read

Example request

curl "https://invoice.avscorp.in/api/v1/lost-reasons" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example response

JSON
{
  "id": "clx8lrs00000000000000001",
  "name": "Price",
  "isArchived": false
}

Possible errors: unauthorized, insufficient_scope, forbidden