Skip to content
AISARAISAR
REST API

Deals

The CRM layer of AISAR: deals attached to funnels and stages, deal tasks (calls, meetings, follow-ups), and per-company reference lists of deal types and lost reasons. Ownership of a deal or task is always checked by company_id — touching another company's record returns 404, not 403. Every endpoint requires an active subscription and the plan's deals feature.

Funnel/stage consistency

Updating a deal (POST /deals/{deal}) obeys funnel/stage consistency rules: changing funnel_id requires an explicit funnel_stage_id in the same request (otherwise 422 "A funnel_stage_id is required when changing funnel_id." — the old silent jump to the first stage was removed), and the funnel_stage_id itself must belong to the chosen funnel (otherwise 422 "Selected stage does not belong to the selected funnel."). If you change the stage without an explicit status, the status is derived from the stage type: successwon, failedlost, anything else→open.

Closing a deal: won and lost

Moving status to lost (including implicitly, by moving into a failed-typed stage) requires a lost_reason_id from the lost-reasons reference or a free-form lost_reason (otherwise 422 "A lost reason is required when marking a deal as lost."); a transition to won/lost snapshots closed_amount/closed_currency at close time, and moving back to open clears closed_at, lost_reason, lost_reason_id and the amount snapshot.

Deletion and restore

Deleting a deal is soft (deleted_at, the id and dialog links are kept), and POST /deals/{deal}/restore (permission deal.delete) restores it idempotently.

Activity timeline

GET /deals/{deal}/activities returns an append-only timeline whose type is one of created|stage_changed|field_changed|note|task_created|task_completed|won|lost|responsible_changed|system; on system entries (automations, AI tools, inbound Bitrix24) actor is null.

Deal tasks

Deal tasks are updated with PATCH /deal-tasks/{task} (the legacy /deals/{deal} deliberately stays on POST): overdue is a derived field (due_at < now() while status=open), the mine filter aliases the current user, closing (done/cancelled) records completed_at, and changing assigned_user_id sends the assignee an in-app notification.

Reference lists and settings

Lost reasons (/lost-reasons; editing needs the lost_reason.manage permission) are unique by name within a company. The auto-creation settings (/company/deal-settings) return an already-resolved default_currency (defaulting to KZT when it is null in the database); auto_create_deal_enabled cannot be turned on without at least one funnel in the company (422).

Endpoints

MethodPath
GET/v1/deals

List deals (filters: funnel_id, status, contact_id, responsible_user_id)

POST/v1/deals

Create a deal

GET/v1/deals/{deal}

Get a deal

POST/v1/deals/{deal}

Update a deal

DELETE/v1/deals/{deal}

Delete a deal (soft delete)

POST/v1/deals/{deal}/restore

Restore a soft-deleted deal

GET/v1/deals/{deal}/activities

Deal activity feed (timeline)

POST/v1/deals/{deal}/notes

Add a note to the deal timeline

GET/v1/deals/{deal}/tasks

Tasks attached to a deal

GET/v1/company/deal-settings

Company deal auto-creation settings

POST/v1/company/deal-settings

Save deal auto-creation settings

GET/v1/deal-tasks

List company tasks (filters: status, assigned_user_id, deal_id, overdue, mine)

POST/v1/deal-tasks

Create a task

PATCH/v1/deal-tasks/{task}

Update or close a task

DELETE/v1/deal-tasks/{task}

Delete a task

GET/v1/deal-types

List deal types

POST/v1/deal-types

Create a deal type

PATCH/v1/deal-types/{dealType}

Update a deal type

DELETE/v1/deal-types/{dealType}

Delete a deal type

GET/v1/lost-reasons

List lost reasons

POST/v1/lost-reasons

Create a lost reason

PATCH/v1/lost-reasons/{lostReason}

Update a lost reason

DELETE/v1/lost-reasons/{lostReason}

Delete a lost reason

Examples

Create a deal

Request

bash
curl -X POST https://api.aisar.app/v1/deals \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "contact_id": 123,
    "funnel_id": 1,
    "funnel_stage_id": 3,
    "title": "Office renovation",
    "amount": "5000.00",
    "currency": "KZT",
    "source": "api",
    "responsible_user_id": 5
  }'

Response

json
{
  "data": {
    "id": 501,
    "company_id": 1,
    "contact_id": 123,
    "funnel_id": 1,
    "funnel_stage_id": 3,
    "title": "Office renovation",
    "amount": "5000.00",
    "currency": "KZT",
    "status": "open",
    "type_id": null,
    "source": "api",
    "utm_source": null,
    "utm_medium": null,
    "utm_campaign": null,
    "probability": null,
    "comments": null,
    "begin_date": null,
    "responsible_user_id": 5,
    "expected_close_date": null,
    "closed_at": null,
    "lost_reason": null,
    "lost_reason_id": null,
    "closed_amount": null,
    "closed_currency": null,
    "stage_changed_at": "2026-03-15T10:00:00.000000Z",
    "channel": null,
    "custom_fields": null,
    "created_at": "2026-03-15T10:00:00.000000Z",
    "updated_at": "2026-03-15T10:00:00.000000Z"
  }
}

Mark a deal as lost

Request

bash
curl -X POST https://api.aisar.app/v1/deals/501 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "lost",
    "lost_reason_id": 3
  }'

Response

json
{
  "data": {
    "id": 501,
    "status": "lost",
    "lost_reason_id": 3,
    "lost_reason": null,
    "closed_amount": "5000.00",
    "closed_currency": "KZT",
    "closed_at": "2026-03-17T09:00:00.000000Z",
    "stage_changed_at": "2026-03-17T09:00:00.000000Z",
    "updated_at": "2026-03-17T09:00:00.000000Z"
  }
}

Mark a deal as lost (free-text reason)

Request

bash
curl -X POST https://api.aisar.app/v1/deals/501 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "lost",
    "lost_reason": "Ушли к конкуренту"
  }'

Response

json
{
  "data": {
    "id": 501,
    "status": "lost",
    "lost_reason_id": null,
    "lost_reason": "Ушли к конкуренту",
    "closed_amount": "5000.00",
    "closed_currency": "KZT",
    "closed_at": "2026-03-17T09:00:00.000000Z",
    "stage_changed_at": "2026-03-15T10:00:00.000000Z",
    "updated_at": "2026-03-17T09:00:00.000000Z"
  }
}

Move a deal to another funnel (with a stage)

Request

bash
curl -X POST https://api.aisar.app/v1/deals/501 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "funnel_id": 2,
    "funnel_stage_id": 8,
    "responsible_user_id": 5
  }'

Response

json
{
  "data": {
    "id": 501,
    "funnel_id": 2,
    "funnel_stage_id": 8,
    "status": "open",
    "responsible_user_id": 5,
    "stage_changed_at": "2026-03-16T12:00:00.000000Z",
    "updated_at": "2026-03-16T12:00:00.000000Z"
  }
}

Deal activity feed

Request

bash
curl -X GET "https://api.aisar.app/v1/deals/501/activities?perPage=20" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Response

json
{
  "data": {
    "items": [
      {
        "id": 1,
        "deal_id": 501,
        "type": "stage_changed",
        "actor_user_id": 5,
        "body": null,
        "metadata": { "from": 1, "to": 3 },
        "created_at": "2026-03-15T10:05:00.000000Z",
        "actor": { "id": 5, "name": "Ivan", "lastname": "Petrov" }
      }
    ],
    "pagination": { "page": 1, "perPage": 20, "total": 4, "lastPage": 1 }
  }
}

Note on the deal timeline

Request

bash
curl -X POST https://api.aisar.app/v1/deals/501/notes \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "Клиент просит счёт на юрлицо"
  }'

Response

json
{
  "data": {
    "message": "Note added.",
    "item": {
      "id": 902,
      "deal_id": 501,
      "type": "note",
      "actor_user_id": 5,
      "body": "Клиент просит счёт на юрлицо",
      "metadata": null,
      "created_at": "2026-03-16T09:00:00.000000Z"
    }
  }
}

Deal auto-creation settings

Request

bash
curl -X GET https://api.aisar.app/v1/company/deal-settings \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Response

json
{
  "data": {
    "auto_create_deal_enabled": true,
    "default_funnel_id": 1,
    "default_deal_title_template": "{contact_name}",
    "default_currency": "KZT",
    "has_funnels": true
  }
}

Save deal settings

Request

bash
curl -X POST https://api.aisar.app/v1/company/deal-settings \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "auto_create_deal_enabled": true,
    "default_funnel_id": 1,
    "default_deal_title_template": "{contact_name}",
    "default_currency": "KZT"
  }'

Response

json
{
  "data": {
    "auto_create_deal_enabled": true,
    "default_funnel_id": 1,
    "default_deal_title_template": "{contact_name}",
    "default_currency": "KZT",
    "has_funnels": true
  }
}

List tasks (mine, overdue)

Request

bash
curl -X GET "https://api.aisar.app/v1/deal-tasks?mine=1&overdue=1&perPage=20" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Accept: application/json"

Response

json
{
  "data": {
    "items": [
      {
        "id": 1,
        "company_id": 1,
        "deal_id": 501,
        "contact_id": null,
        "type": "call",
        "title": "Перезвонить клиенту",
        "description": null,
        "due_at": "2026-07-08T09:00:00.000000Z",
        "remind_at": "2026-07-08T08:45:00.000000Z",
        "status": "open",
        "assigned_user_id": 5,
        "completed_at": null,
        "overdue": true,
        "created_at": "2026-07-07T10:00:00.000000Z",
        "updated_at": "2026-07-07T10:00:00.000000Z"
      }
    ],
    "pagination": { "page": 1, "perPage": 20, "total": 7, "lastPage": 1 }
  }
}

Create a deal task

Request

bash
curl -X POST https://api.aisar.app/v1/deal-tasks \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "deal_id": 501,
    "type": "call",
    "title": "Перезвонить клиенту",
    "due_at": "2026-07-08T09:00:00Z",
    "remind_at": "2026-07-08T08:45:00Z",
    "assigned_user_id": 5
  }'

Response

json
{
  "data": {
    "id": 1,
    "company_id": 1,
    "deal_id": 501,
    "contact_id": null,
    "type": "call",
    "title": "Перезвонить клиенту",
    "description": null,
    "due_at": "2026-07-08T09:00:00.000000Z",
    "remind_at": "2026-07-08T08:45:00.000000Z",
    "status": "open",
    "assigned_user_id": 5,
    "completed_at": null,
    "overdue": false,
    "created_at": "2026-07-07T10:00:00.000000Z",
    "updated_at": "2026-07-07T10:00:00.000000Z"
  }
}

Close a task (PATCH)

Request

bash
curl -X PATCH https://api.aisar.app/v1/deal-tasks/1 \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "done"
  }'

Response

json
{
  "data": {
    "id": 1,
    "deal_id": 501,
    "type": "call",
    "status": "done",
    "assigned_user_id": 5,
    "completed_at": "2026-07-08T09:30:00.000000Z",
    "updated_at": "2026-07-08T09:30:00.000000Z"
  }
}

Create a lost reason

Request

bash
curl -X POST https://api.aisar.app/v1/lost-reasons \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Дорого",
    "is_active": true,
    "order": 0
  }'

Response

json
{
  "data": {
    "id": 1,
    "company_id": 1,
    "name": "Дорого",
    "is_active": true,
    "order": 0,
    "created_at": "2026-07-07T10:00:00.000000Z",
    "updated_at": "2026-07-07T10:00:00.000000Z"
  }
}