Skip to content

CRM API

API endpoints for the CRM module. All endpoints require JWT authentication via the token_admin strategy.

Authentication

All endpoints require a valid admin JWT token:

Authorization: Bearer <token>

Permission-based access is enforced per endpoint (see the Auth column in each table).

Prospects

Listing & Queries

MethodPathDescriptionAuth
GET/prospects/groupedProspects grouped by follow-up category (Kanban)Permission 319
GET/prospects/listPaginated prospect list with sorting and filtersPermission 319
GET/prospects/activitiesFollow-up activities in a date range (Calendar)Permission 319
GET/prospects/kpisKPI aggregates per follow-up categoryPermission 319
GET/prospects/{id}Single prospect with notes, contacts, locationsPermission 319

CRUD Operations

MethodPathDescriptionAuth
POST/prospects/processValidate and deduplicate prospects (no DB write)token_admin
POST/prospectsCreate prospects (batch)token_admin
PATCH/prospects/{id}Update prospect fields (name, email, phone, etc.)token_admin
PATCH/prospects/{id}/dataUpdate follow-up data (channel, account value, etc.)Permission 319
PATCH/prospects/{id}/partner-dataUpdate partner prospect data (URL, rating, etc.)crm-partners

Contacts

MethodPathDescriptionAuth
POST/prospects/{id}/contactsAdd contact for a prospectPermission 319
PUT/prospects/{id}/contactsUpdate contact (or default prospect contact)Permission 319
DELETE/prospects/{id}/contactsDelete contact by IDPermission 319

Notes

MethodPathDescriptionAuth
POST/prospects/{id}/notesAdd follow-up notePermission 319
PATCH/prospects/{id}/notes/{noteId}Update note scheduled datePermission 319

Locations

MethodPathDescriptionAuth
POST/prospects/{id}/locationsCreate location for a prospectcrm-menu
PUT/prospects/locations/{id}Update locationcrm-menu
DELETE/prospects/locations/{id}Delete locationcrm-menu

Clients

MethodPathDescriptionAuth
GET/clients/{id}Client details with contacts, notes, integrations, locationsPermission 319
GET/clients/{id}/onboardingClient onboarding dataPermission 319
POST/clients/{id}/contactsAdd contact for a clientPermission 319
POST/clients/{id}/notesAdd follow-up note for a clientPermission 319
PATCH/clients/{id}/dataUpdate client follow-up dataPermission 319
POST/clients/{id}/locationsCreate location for a clientcrm-menu
PUT/clients/locations/{id}Update client locationcrm-menu
DELETE/clients/locations/{id}Delete client locationcrm-menu

Endpoint Details

GET /prospects/grouped

Returns prospects grouped by follow-up category for the Kanban board. Supports pagination per group and extensive filters.

Query Parameters:

ParamTypeRequiredDescription
startnumberNoOffset for pagination
lengthnumberNoPage size
sortBystringNoSort field
sortTypestringNoSort direction
categorynumberNoFilter by specific follow-up category
searchstringNoFree-text search (company name, contact name)
followstringNoFilter by follow-up status ID(s)
typestringNoFilter by prospect type
onboardingstringNoFilter by onboarding status
ecommercestringNoFilter by ecommerce type
campaingstringNoFilter by campaign
salesmanstringNoFilter by assigned salesman (requires all-prospects)
startDatestringNoDate range start (requires all-prospects)
endDatestringNoDate range end (requires all-prospects)
kaestringNoFilter by KAE assignment
kae_ltlstringNoFilter by KAE LTL assignment
csrstringNoFilter by CSR assignment
csr_ltlstringNoFilter by CSR LTL assignment
fullfilmentstringNoFilter by Fulfillment assignment
wmsstringNoFilter by WMS assignment
ecartpaystringNoFilter by Ecartpay assignment
parapaquetesstringNoFilter by Parapaquetes assignment
sourcestringNocompany (default) or partner
countersbooleanNoInclude record counts per category
reportbooleanNoReport mode flag

Response (200):

json
{
  "categories": [
    {
      "id": 1,
      "name": "new_lead",
      "records": [
        {
          "id": 42,
          "company_name": "Acme Corp",
          "name": "John Doe",
          "email": "john@acme.com",
          "follow_up_id": 1,
          "follow_name": "new_lead",
          "balance": 0,
          "account_value": 5000,
          "last_contact": "2026-03-15T10:30:00Z",
          "salesman_name": "Maria Garcia",
          "verified": true,
          "tier": "gold",
          "monthly_shipments": 150,
          "services": [1, 3, 5]
        }
      ],
      "count": 23
    }
  ]
}

GET /prospects/list

Returns a paginated, sortable list of prospects for the data table view.

Query Parameters:

All parameters from /prospects/grouped plus:

ParamTypeRequiredDescription
startnumberNoOffset (default: 0)
lengthnumberNoPage size (default: 25)
sortBystringNoColumn to sort by
sortTypestringNoasc or desc
weightRangestringNoFilter by weight range
contentIdstringNoFilter by content type
planTypeIdstringNoFilter by plan type
minShipmentsnumberNoMinimum monthly shipments
leadStatusstringNoFilter by lead status
nextContact[0]stringNoNext contact date range start
nextContact[1]stringNoNext contact date range end
estimatedCloseDate[0]stringNoEstimated close date range start
estimatedCloseDate[1]stringNoEstimated close date range end
estimatedCloseMonthstringNoFilter by estimated close month
commercialOfferDate[0]stringNoCommercial offer date range start
commercialOfferDate[1]stringNoCommercial offer date range end
hasRechargestringNo0 or 1 — filter by recharge status

Response (200):

json
{
  "recordsTotal": 1250,
  "recordsFiltered": 89,
  "data": [
    {
      "id": 42,
      "company_name": "Acme Corp",
      "follow_name": "contacted",
      "salesman_name": "Maria Garcia",
      "balance": 15000.00,
      "account_value": 5000,
      "first_contact": "2026-01-15",
      "last_contact": "2026-03-10",
      "days_uc": 5,
      "days_without_contact": 9,
      "next_contact": "2026-03-20",
      "monthly_shipments_desc": "100-500",
      "campaign": "Q1-2026",
      "lead_status": "qualified",
      "estimated_close_date": "2026-04-15"
    }
  ]
}

GET /prospects/activities

Returns follow-up activities within a date range for the calendar view.

Query Parameters:

ParamTypeRequiredDescription
startDatestringYesDate range start
endDatestringYesDate range end
searchstringNoFree-text search
followstringNoFilter by follow-up status
typestringNoFilter by prospect type
onboardingstringNoFilter by onboarding status
ecommercestringNoFilter by ecommerce type
campaingstringNoFilter by campaign
salesmanstringNoFilter by assigned salesman
kae ... parapaquetesstringNoRole-based filters

Response (200):

json
[
  {
    "id": 101,
    "entity_name": "Acme Corp",
    "entity_type": "prospect",
    "entity_id": 42,
    "action": "call",
    "comment": "Discussed pricing options",
    "scheduled_date": "2026-03-15T09:00:00Z",
    "created_by_name": "Maria Garcia",
    "follow_name": "negotiation"
  }
]

GET /prospects/kpis

Returns KPI aggregates (e.g., total account value) per follow-up category.

Query Parameters: Same filters as /prospects/grouped (excluding pagination).

Response (200):

json
[
  {
    "category_id": 1,
    "category_name": "new_lead",
    "total_value": 125000,
    "count": 23
  }
]

GET /prospects/{id}

Returns full prospect details including notes, contacts, and locations.

Path Parameters:

ParamTypeRequiredDescription
idnumberYesProspect ID

Query Parameters:

ParamTypeRequiredDescription
sourcestringNocompany (default) or partner

Response (200):

json
{
  "prospect": {
    "id": 42,
    "name": "John Doe",
    "company_name": "Acme Corp",
    "email": "john@acme.com",
    "phone_code": "52",
    "phone": "5551234567",
    "company_id": null,
    "follow_up_id": 3,
    "locale_id": 1,
    "type": 1,
    "status": 1,
    "created_by": 10,
    "created_at": "2026-01-15T08:00:00Z"
  },
  "follow_data": {
    "channel": "website",
    "account_value": 5000,
    "monthly_shipments": 150,
    "ecommerce_type_id": 2,
    "account_type": "sme",
    "estimated_close_date": "2026-04-15"
  },
  "notes": [],
  "contacts": [],
  "locations": []
}

POST /prospects/process

Validates and deduplicates a batch of prospects without writing to the database. Used as a preview step during CSV import.

Request:

json
[
  {
    "name": "John Doe",
    "company": "Acme Corp",
    "email": "john@acme.com",
    "phone": 5551234567,
    "code": 52,
    "locale": 1
  }
]

Response (200):

json
{
  "inserts": [
    {
      "name": "John Doe",
      "company": "Acme Corp",
      "email": "john@acme.com",
      "phone": 5551234567,
      "code": 52,
      "locale": 1
    }
  ],
  "updates": [],
  "errors": [
    {
      "email": "duplicate@example.com",
      "code": "DUPLICATE_EMAIL",
      "existing_id": 99
    }
  ]
}

POST /prospects

Creates prospects in batch from validated data. Triggers Respondio integration for new leads.

Request:

json
[
  {
    "name": "John Doe",
    "company": "Acme Corp",
    "email": "john@acme.com",
    "phone": 5551234567,
    "code": 52,
    "locale": 1,
    "type": 1,
    "monthly_shipments": 150,
    "follow_up_id": 1
  }
]
FieldTypeRequiredDescription
namestringNoContact name
companystringNoCompany name
emailstringNoEmail address
phonenumberNoPhone number
codenumberNoPhone country code
localenumberNoLocale/country ID
typenumberNo1 = prospect (default), 2 = client, 3 = partner
monthly_shipmentsstring/numberNoEstimated monthly shipments
follow_up_idnumberNoInitial follow-up status

Response (200):

json
{
  "inserts": [
    { "id": 42, "email": "john@acme.com" }
  ],
  "errors": []
}

POST /prospects/{id}/notes

Creates a follow-up note for a prospect or client, optionally updating the follow-up status.

Request:

json
{
  "follow": 3,
  "action": "call",
  "note": "Discussed pricing options. Client interested in enterprise plan.",
  "scheduled_date": "2026-03-20T09:00:00Z"
}
FieldTypeRequiredDescription
follownumberNoNew follow-up status ID (updates current status)
actionstringNoAction type: call, whatsapp, email, meeting, sms, other
notestringYesNote content
scheduled_dateISO dateNoScheduled follow-up date/time

PATCH /prospects/{id}/notes/{noteId}

Updates the scheduled date of an existing note.

Request:

json
{
  "scheduled_date": "2026-03-25T14:00:00Z",
  "origin": "prospect"
}
FieldTypeRequiredDescription
scheduled_dateISO dateYesNew scheduled date (null to remove)
originstringYesprospect or company

PATCH /prospects/{id}/data

Updates follow-up metadata for a prospect.

Request:

json
{
  "channel": "referral",
  "account_value": 8000,
  "monthly_shipments": 200,
  "ecommerce_type_id": 3,
  "weight_id": 2,
  "content_id": 1,
  "account_type": "enterprise",
  "estimated_close_date": "2026-05-01",
  "annotations": "High-priority account, needs custom pricing."
}
FieldTypeRequiredDescription
namestringNoDisplay name
ecommerce_type_idnumberNoE-commerce platform type
channelstringNoAcquisition channel
account_valuenumberNoEstimated account value
localenumberNoLocale ID
monthly_shipmentsnumberNoMonthly shipment estimate
weight_idnumberNoWeight range category
content_idnumberNoContent type
annotationsstringNoFree-text annotations
account_typestringNoindividual, startup, sme, enterprise, corporate
estimated_close_dateISO dateNoExpected close date

PATCH /prospects/{id}

Updates core prospect fields.

Request:

json
{
  "company_name": "Acme Corporation",
  "name": "John Doe",
  "email": "john.doe@acme.com",
  "phone_code": "52",
  "phone": "5559876543",
  "created_by": 15
}
FieldTypeRequiredDescription
company_namestringNoCompany name
namestringNoContact name
emailstringNoEmail (validated)
phone_codestringNoCountry phone code
phonestringNoPhone number
created_bynumberNoReassign to another admin

PATCH /prospects/{id}/partner-data

Updates partner-specific data for type-3 prospects. Requires crm-partners permission.

Request:

json
{
  "url": "https://partner-store.com",
  "partner_type_id": 2,
  "partner_origin_id": 1,
  "rating": 4,
  "locale_id": 1,
  "social_network": "@partnerstore"
}
FieldTypeRequiredDescription
urlstringYesPartner website URL
partner_type_idnumberYesPartner type
partner_origin_idnumberYesPartner origin
ratingnumberYesRating 1-5
locale_idnumberYesLocale ID
social_networkstringNoSocial media handle (max 150 chars)

POST /prospects/{id}/contacts

Adds a new contact to a prospect.

Request:

json
{
  "name": "Jane Smith",
  "email": "jane@acme.com",
  "phone_code": "52",
  "phone": "5559876543",
  "position": "CTO"
}
FieldTypeRequiredDescription
namestringYesContact name
emailstringYesContact email
phone_codestringYesCountry phone code
phonestringYesPhone number
positionstringNoJob title/position

PUT /prospects/{id}/contacts

Updates an existing contact. If isDefault is true, updates the primary prospect record instead of extra_contacts.

Request:

json
{
  "name": "Jane Smith",
  "email": "jane.smith@acme.com",
  "phone_code": "52",
  "phone": "5559876543",
  "position": "VP Engineering",
  "isDefault": false
}

DELETE /prospects/{id}/contacts

Deletes a contact from extra_contacts. The {id} path parameter refers to the contact ID.


POST /prospects/{id}/locations

Creates a location for a prospect. Requires crm-menu permission.

Request:

json
{
  "name": "Main Office",
  "link": "https://maps.google.com/?q=...",
  "type": "headquarters"
}
FieldTypeRequiredDescription
namestringYesLocation name (max 50 chars)
linkstringYesMap URL (max 150 chars)
typestringYesoffice, warehouse, branch, headquarters, distribution_center

PUT /prospects/locations/{id}

Updates an existing location. Same fields as POST, all optional.

DELETE /prospects/locations/{id}

Deletes a location by ID.


Client Endpoints

GET /clients/{id}

Returns full client details by company ID, including contacts, notes, integrations, locations, and onboarding data.

Path Parameters:

ParamTypeRequiredDescription
idnumberYesCompany ID

Response (200):

json
{
  "company": {
    "id": 100,
    "company_name": "Acme Corp",
    "balance": 15000.00,
    "follow_up_id": 5,
    "follow_name": "active_client"
  },
  "follow_data": {},
  "notes": [],
  "contacts": [],
  "locations": [],
  "integrations": [],
  "onboarding": {}
}

GET /clients/{id}/onboarding

Returns onboarding data for a client.

Query Parameters:

ParamTypeRequiredDescription
translatebooleanNoTranslate onboarding keys (default: false)

POST /clients/{id}/contacts

Same payload as POST /prospects/{id}/contacts.

POST /clients/{id}/notes

Same payload as POST /prospects/{id}/notes.

PATCH /clients/{id}/data

Same payload as PATCH /prospects/{id}/data.

POST /clients/{id}/locations

Same payload as POST /prospects/{id}/locations. Requires crm-menu permission.

PUT /clients/locations/{id}

Same payload as PUT /prospects/locations/{id}. Requires crm-menu permission.

DELETE /clients/locations/{id}

Deletes a client location by ID. Requires crm-menu permission.


Common Error Responses

All errors follow the Boom format:

json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Descriptive error message"
}
StatusWhen
400Validation failed (Joi schema)
401Missing or invalid JWT
403Insufficient permissions for the action
404Prospect, client, contact, or location not found
409Duplicate email/phone detected during creation
422Malformed request data (Boom badData)

Validation Notes

  • Email uniqueness is checked on contact update (PUT /prospects/{id}/contacts) against both prospection_users and users tables.
  • Phone numbers are validated as numeric values during prospect creation.
  • Location types are restricted to: office, warehouse, branch, headquarters, distribution_center.
  • Partner data rating must be an integer between 1 and 5.
  • The source query parameter on listing endpoints defaults to company and can be set to partner for partner-type prospects.

Envia Admin