Leads
Sales · 6 operations
List leads
/api/leadLeads (sales deals) with filters: pipeline, current stage (stageIds) or its kind (stageTypes: INCOMING, REGULAR, CLOSED_WON, CLOSED_LOST), source, managers or hasNoManager, created range, a move into a stage within a range (stageEnteredStart/End: "won this month" is stageTypes=CLOSED_WON with that range), stuck leads (stageUnchangedSince), refusal reasons, linked student. Paginated; "total" is the full count.
list_leads
Query parameters · 48
pagemin 1 · default 1pageSize1–250 · default 20stageTypesKind of the current stage: CLOSED_WON for won deals, CLOSED_LOST for lost ones, INCOMING and REGULAR for open ones.One of: REGULAR INCOMING CLOSED_WON CLOSED_LOSTsortByOne of: lead pipeline stage sourceOfLead createdAtsortOrderOne of: ASC DESCleadIds—pipelineId—search—Show 40 more
nameOfLeadlength max 150studentId—reasonForRefusalId—reasonForRefusalIds—managerIds—hasNoManagerOnly leads nobody is responsible for.stageIdsCurrent stage.sourceOfLeadIds—createdStartCreated from, a school-local calendar day.createdEndCreated until, inclusive: the end of that school-local day.stageEnteredStartMoved into a stage from this school-local day; with stageIds or stageTypes, into one of those stages.
"Won this month" is stageTypes=CLOSED_WON with this range.stageEnteredEndMoved into a stage until this school-local day, inclusive.stageUnchangedSinceNot moved between stages since this school-local day: leads stuck in their current stage.note—studentStatusOfStudentId—studentFirstName—studentLastName—studentMiddleName—studentIsChild—studentGenderOne of: MALE FEMALEstudentTeacherIds—studentManagerIds—studentReasonForRefusalIds—studentTeachingProgramIds—studentClassOfStudentIds—studentSubscriptionIds—studentBalanceFrom—studentBalanceTo—studentLessonsLeftFrom—studentLessonsLeftTo—studentNote—studentHasGroup—studentHasNoGroup—studentHasNoLessons—studentIsDebtor—studentHasFreeLessons—studentHasFreeTrialLessons—studentHasExpiredSubscription—studentIsArchival—cf—Response · 200
application/json
statusCodeexample 200message—data4 fields
total—totalPages—currentPage—leads13 fields
costOfLead—leadId—pipelineId—stageId—nameOfLead—contacts3 fields
type—value—label—note—avatarUrl—boughtWithoutTrial—archivedAtformat YYYY-MM-DDTHH:mm:ssupdatedAtformat YYYY-MM-DDTHH:mm:sscreatedAtformat YYYY-MM-DDTHH:mm:sscustomFieldsany keyscurl "https://your-school.rist.pro/api/lead" \
-H "Authorization: Bearer $RIST_API_KEY"const response = await fetch("https://your-school.rist.pro/api/lead", {
headers: {
Authorization: `Bearer ${process.env.RIST_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://your-school.rist.pro/api/lead",
headers={"Authorization": f"Bearer {os.environ['RIST_API_KEY']}"},
)
response.raise_for_status()
data = response.json()["data"]{
"statusCode": 200,
"message": "Operation completed successfully",
"data": {
"total": 0,
"totalPages": 0,
"currentPage": 0,
"leads": [
{
"costOfLead": 0,
"leadId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "string",
"value": "string",
"label": "string"
}
],
"note": "string",
"avatarUrl": "string",
"boughtWithoutTrial": false,
"archivedAt": "2026-11-09T14:30:00",
"updatedAt": "2026-11-09T14:30:00",
"createdAt": "2026-11-09T14:30:00",
"customFields": {}
}
]
}
}Count leads by stage, source or manager
/api/lead/breakdownHow many leads match the GET /api/lead filters, per stage (funnel order), pipeline, source, manager or refusal reason (groupBy). Lost leads by reason: groupBy=reasonForRefusal, stageTypes=CLOSED_LOST with a stageEntered range. One call instead of paging through GET /api/lead.
count_leads
Query parameters · 45
stageTypesKind of the current stage: CLOSED_WON for won deals, CLOSED_LOST for lost ones, INCOMING and REGULAR for open ones.One of: REGULAR INCOMING CLOSED_WON CLOSED_LOSTcf—leadIds—pipelineId—search—nameOfLeadlength max 150studentId—reasonForRefusalId—Show 37 more
reasonForRefusalIds—managerIds—hasNoManagerOnly leads nobody is responsible for.stageIdsCurrent stage.sourceOfLeadIds—createdStartCreated from, a school-local calendar day.createdEndCreated until, inclusive: the end of that school-local day.stageEnteredStartMoved into a stage from this school-local day; with stageIds or stageTypes, into one of those stages.
"Won this month" is stageTypes=CLOSED_WON with this range.stageEnteredEndMoved into a stage until this school-local day, inclusive.stageUnchangedSinceNot moved between stages since this school-local day: leads stuck in their current stage.note—studentStatusOfStudentId—studentFirstName—studentLastName—studentMiddleName—studentIsChild—studentGenderOne of: MALE FEMALEstudentTeacherIds—studentManagerIds—studentReasonForRefusalIds—studentTeachingProgramIds—studentClassOfStudentIds—studentSubscriptionIds—studentBalanceFrom—studentBalanceTo—studentLessonsLeftFrom—studentLessonsLeftTo—studentNote—studentHasGroup—studentHasNoGroup—studentHasNoLessons—studentIsDebtor—studentHasFreeLessons—studentHasFreeTrialLessons—studentHasExpiredSubscription—studentIsArchival—groupByWhat to count leads by; stage keeps the funnel order.One of: stage pipeline source manager reasonForRefusalResponse · 200
application/json
statusCodeexample 200message—data3 fields
omittedRowsRows left out by the limittotalRecords matching the filters; a record counted in several rows (a student with two teachers) counts here once.rows3 fields
idId of the grouped value (teacher id, stage id, weekday 1-7) or its code (lesson status); null means "no value".name—count—curl "https://your-school.rist.pro/api/lead/breakdown" \
-H "Authorization: Bearer $RIST_API_KEY"const response = await fetch("https://your-school.rist.pro/api/lead/breakdown", {
headers: {
Authorization: `Bearer ${process.env.RIST_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://your-school.rist.pro/api/lead/breakdown",
headers={"Authorization": f"Bearer {os.environ['RIST_API_KEY']}"},
)
response.raise_for_status()
data = response.json()["data"]{
"statusCode": 200,
"message": "Operation completed successfully",
"data": {
"omittedRows": 0,
"total": 0,
"rows": [
{
"id": 1,
"name": "string",
"count": 0
}
]
}
}Get lead
/api/lead/{id}One lead with its pipeline stage, manager, contacts and custom fields.
get_lead
Path parameters · 1
id—Response · 200
application/json
statusCodeexample 200message—data13 fields
costOfLead—leadId—pipelineId—stageId—nameOfLead—contacts3 fields
type—value—label—note—avatarUrl—boughtWithoutTrial—archivedAtformat YYYY-MM-DDTHH:mm:ssupdatedAtformat YYYY-MM-DDTHH:mm:sscreatedAtformat YYYY-MM-DDTHH:mm:sscustomFieldsany keyscurl "https://your-school.rist.pro/api/lead/1" \
-H "Authorization: Bearer $RIST_API_KEY"const response = await fetch("https://your-school.rist.pro/api/lead/1", {
headers: {
Authorization: `Bearer ${process.env.RIST_API_KEY}`,
},
});
const { data } = await response.json();import os
import requests
response = requests.get(
"https://your-school.rist.pro/api/lead/1",
headers={"Authorization": f"Bearer {os.environ['RIST_API_KEY']}"},
)
response.raise_for_status()
data = response.json()["data"]{
"statusCode": 200,
"message": "Operation completed successfully",
"data": {
"costOfLead": 0,
"leadId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "string",
"value": "string",
"label": "string"
}
],
"note": "string",
"avatarUrl": "string",
"boughtWithoutTrial": false,
"archivedAt": "2026-11-09T14:30:00",
"updatedAt": "2026-11-09T14:30:00",
"createdAt": "2026-11-09T14:30:00",
"customFields": {}
}
}Create lead
/api/leadCreate a lead in a pipeline stage. A manager is assigned automatically if the stage distributes leads.
create_lead
Request body
application/json · object
studentIdmin 1sourceOfLeadIdmin 1reasonForRefusalIdmin 1managerIdmin 1pipelineIdmin 1stageIdmin 1nameOfLeadlength 1–150contacts3 fields
typeOne of: PHONE EMAIL MESSENGER URLvaluelength 1–255labellength max 50avatarUrllength max 500notelength max 1500costOfLeadmin 0labelsOfStatistic2 fields
labelOfStatisticIdmin 1valuelength max 70tagIdsmin 1customFieldsany keysResponse · 201
application/json
statusCodeexample 201message—data13 fields
costOfLead—leadId—pipelineId—stageId—nameOfLead—contacts3 fields
type—value—label—note—avatarUrl—boughtWithoutTrial—archivedAtformat YYYY-MM-DDTHH:mm:ssupdatedAtformat YYYY-MM-DDTHH:mm:sscreatedAtformat YYYY-MM-DDTHH:mm:sscustomFieldsany keyscurl -X POST "https://your-school.rist.pro/api/lead" \
-H "Authorization: Bearer $RIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"studentId": 1,
"sourceOfLeadId": 1,
"reasonForRefusalId": 1,
"managerId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "PHONE",
"value": "string",
"label": "string"
}
],
"avatarUrl": "string",
"note": "string",
"costOfLead": 0,
"labelsOfStatistic": [
{
"labelOfStatisticId": 1,
"value": "string"
}
],
"tagIds": [
1
],
"customFields": {}
}'const response = await fetch("https://your-school.rist.pro/api/lead", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.RIST_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"studentId": 1,
"sourceOfLeadId": 1,
"reasonForRefusalId": 1,
"managerId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "PHONE",
"value": "string",
"label": "string"
}
],
"avatarUrl": "string",
"note": "string",
"costOfLead": 0,
"labelsOfStatistic": [
{
"labelOfStatisticId": 1,
"value": "string"
}
],
"tagIds": [
1
],
"customFields": {}
}),
});
const { data } = await response.json();import os
import requests
response = requests.post(
"https://your-school.rist.pro/api/lead",
headers={"Authorization": f"Bearer {os.environ['RIST_API_KEY']}"},
json={
"studentId": 1,
"sourceOfLeadId": 1,
"reasonForRefusalId": 1,
"managerId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "PHONE",
"value": "string",
"label": "string"
}
],
"avatarUrl": "string",
"note": "string",
"costOfLead": 0,
"labelsOfStatistic": [
{
"labelOfStatisticId": 1,
"value": "string"
}
],
"tagIds": [
1
],
"customFields": {}
},
)
response.raise_for_status()
data = response.json()["data"]{
"statusCode": 201,
"message": "Operation completed successfully",
"data": {
"costOfLead": 0,
"leadId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "string",
"value": "string",
"label": "string"
}
],
"note": "string",
"avatarUrl": "string",
"boughtWithoutTrial": false,
"archivedAt": "2026-11-09T14:30:00",
"updatedAt": "2026-11-09T14:30:00",
"createdAt": "2026-11-09T14:30:00",
"customFields": {}
}
}Update lead
/api/lead/{id}Change fields of a lead. Send only the fields to change. To move between stages use PATCH /api/lead/stage/{id}.
update_lead
Path parameters · 1
id—Request body
application/json · object
sourceOfLeadIdmin 1reasonForRefusalIdmin 1managerIdmin 1pipelineIdmin 1stageIdmin 1nameOfLeadlength 1–150contacts3 fields
typeOne of: PHONE EMAIL MESSENGER URLvaluelength 1–255labellength max 50avatarUrllength max 500notelength max 1500costOfLeadmin 0boughtWithoutTrial—labelsOfStatistic2 fields
labelOfStatisticIdmin 1valuelength max 70tagIdsmin 1customFieldsany keysResponse · 200
application/json
statusCodeexample 200message—data13 fields
costOfLead—leadId—pipelineId—stageId—nameOfLead—contacts3 fields
type—value—label—note—avatarUrl—boughtWithoutTrial—archivedAtformat YYYY-MM-DDTHH:mm:ssupdatedAtformat YYYY-MM-DDTHH:mm:sscreatedAtformat YYYY-MM-DDTHH:mm:sscustomFieldsany keyscurl -X PATCH "https://your-school.rist.pro/api/lead/1" \
-H "Authorization: Bearer $RIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sourceOfLeadId": 1,
"reasonForRefusalId": 1,
"managerId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "PHONE",
"value": "string",
"label": "string"
}
],
"avatarUrl": "string",
"note": "string",
"costOfLead": 0,
"boughtWithoutTrial": false,
"labelsOfStatistic": [
{
"labelOfStatisticId": 1,
"value": "string"
}
],
"tagIds": [
1
],
"customFields": {}
}'const response = await fetch("https://your-school.rist.pro/api/lead/1", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RIST_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"sourceOfLeadId": 1,
"reasonForRefusalId": 1,
"managerId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "PHONE",
"value": "string",
"label": "string"
}
],
"avatarUrl": "string",
"note": "string",
"costOfLead": 0,
"boughtWithoutTrial": false,
"labelsOfStatistic": [
{
"labelOfStatisticId": 1,
"value": "string"
}
],
"tagIds": [
1
],
"customFields": {}
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://your-school.rist.pro/api/lead/1",
headers={"Authorization": f"Bearer {os.environ['RIST_API_KEY']}"},
json={
"sourceOfLeadId": 1,
"reasonForRefusalId": 1,
"managerId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "PHONE",
"value": "string",
"label": "string"
}
],
"avatarUrl": "string",
"note": "string",
"costOfLead": 0,
"boughtWithoutTrial": False,
"labelsOfStatistic": [
{
"labelOfStatisticId": 1,
"value": "string"
}
],
"tagIds": [
1
],
"customFields": {}
},
)
response.raise_for_status()
data = response.json()["data"]{
"statusCode": 200,
"message": "Operation completed successfully",
"data": {
"costOfLead": 0,
"leadId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "string",
"value": "string",
"label": "string"
}
],
"note": "string",
"avatarUrl": "string",
"boughtWithoutTrial": false,
"archivedAt": "2026-11-09T14:30:00",
"updatedAt": "2026-11-09T14:30:00",
"createdAt": "2026-11-09T14:30:00",
"customFields": {}
}
}Move lead to stage
/api/lead/stage/{id}Move a lead to another pipeline stage. Moving to a refusal stage may require a refusal reason.
move_lead_stage
Path parameters · 1
id—Request body
application/json · object
stageIdmin 1reasonForRefusalIdmin 1Response · 200
application/json
statusCodeexample 200message—data13 fields
costOfLead—leadId—pipelineId—stageId—nameOfLead—contacts3 fields
type—value—label—note—avatarUrl—boughtWithoutTrial—archivedAtformat YYYY-MM-DDTHH:mm:ssupdatedAtformat YYYY-MM-DDTHH:mm:sscreatedAtformat YYYY-MM-DDTHH:mm:sscustomFieldsany keyscurl -X PATCH "https://your-school.rist.pro/api/lead/stage/1" \
-H "Authorization: Bearer $RIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stageId": 1,
"reasonForRefusalId": 1
}'const response = await fetch("https://your-school.rist.pro/api/lead/stage/1", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.RIST_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"stageId": 1,
"reasonForRefusalId": 1
}),
});
const { data } = await response.json();import os
import requests
response = requests.patch(
"https://your-school.rist.pro/api/lead/stage/1",
headers={"Authorization": f"Bearer {os.environ['RIST_API_KEY']}"},
json={
"stageId": 1,
"reasonForRefusalId": 1
},
)
response.raise_for_status()
data = response.json()["data"]{
"statusCode": 200,
"message": "Operation completed successfully",
"data": {
"costOfLead": 0,
"leadId": 1,
"pipelineId": 1,
"stageId": 1,
"nameOfLead": "string",
"contacts": [
{
"type": "string",
"value": "string",
"label": "string"
}
],
"note": "string",
"avatarUrl": "string",
"boughtWithoutTrial": false,
"archivedAt": "2026-11-09T14:30:00",
"updatedAt": "2026-11-09T14:30:00",
"createdAt": "2026-11-09T14:30:00",
"customFields": {}
}
}