Your AI Connector Docs

Deals API

A deal is one sales opportunity on your Sales Pipeline board — a title, a value, the stage it sits in, and optionally the contact it belongs to and the team member it is assigned to. This guide covers reading and managing deals over the API.

All examples below show the ?apiKey= query form in cURL and the X-API-Key header in JavaScript and Python — either works on every endpoint.


The deal object

{
  "id": "deal_abc123",
  "title": "Annual plan – Jane's Clinic",
  "description": "Asked for pricing on the annual plan.",
  "company": "Jane's Clinic",
  "notes": "Prefers a call after 5pm.",
  "stage": "stage-2",
  "pipeline_id": "default",
  "value": 4800,
  "probability": 60,
  "priority": "high",
  "status": "open",
  "source": "whatsapp",
  "position": 0,
  "contact_id": "ctc_9f8e7d",
  "assigned_to": "usr_4a2b",
  "tags": ["clinic"],
  "close_date": "2026-10-01T00:00:00.000Z",
  "created_at": "2026-09-05T09:12:00.000Z",
  "updated_at": "2026-09-05T09:40:00.000Z",
  "stage_entered_at": "2026-09-05T09:40:00.000Z"
}

stage is the id of one of your pipeline stages — read them with GET /pipelines (see Pipelines below). Stage ids are unique across all your pipelines, so pipeline_id is derived from the stage and is read-only: default is your main pipeline, and it is null when the stage no longer exists. Timestamps are ISO 8601.

A deal stores only the fields shown above. When you create or update one, any other field is refused with a 400 that names it, so nothing you send is silently lost. Keep extra data on the linked contact’s custom fields.


List deals

GET /deals — returns the deals on your account, newest first.

Query parameters (all optional): stage (a stage id), pipeline_id (only the deals on that pipeline), contact_id, limit (default 50, max 200), cursor (from the previous page’s next_cursor).

cURL

curl "https://api.youraiconnector.com/v1/deals?apiKey=YOUR_API_KEY&stage=stage-2&limit=50"

JavaScript

const res = await fetch("https://api.youraiconnector.com/v1/deals?stage=stage-2&limit=50", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { deals, next_cursor } = await res.json();

Python

res = requests.get(
    "https://api.youraiconnector.com/v1/deals",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"stage": "stage-2", "limit": 50},
)
deals = res.json()["deals"]

Response (200)

{ "success": true, "deals": [{ "id": "deal_abc123", "title": "Annual plan – Jane's Clinic", "...": "..." }], "next_cursor": null }

Get a deal

GET /deals/{dealId}

curl "https://api.youraiconnector.com/v1/deals/deal_abc123?apiKey=YOUR_API_KEY"

Response (200)

{ "success": true, "deal": { "id": "deal_abc123", "title": "Annual plan – Jane's Clinic", "...": "..." } }

A deal that does not exist, or belongs to another account, returns 404.


Create a deal

POST /deals — title and stage are required; stage must be one of your pipeline’s stage ids.

curl -X POST "https://api.youraiconnector.com/v1/deals?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Annual plan – Jane'"'"'s Clinic", "stage": "stage-1", "value": 4800, "contact_id": "ctc_9f8e7d" }'

Response (201)

{ "success": true, "deal_id": "deal_abc123" }

Update a deal

PUT /deals/{dealId} — send only the fields you want to change (title, description, notes, value, stage, status, priority, contact_id, …). value must be a number.

curl -X PUT "https://api.youraiconnector.com/v1/deals/deal_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "value": 5200, "priority": "high" }'

Response (200): { "success": true, "deal_id": "deal_abc123" }


Move a deal to another stage

POST /deals/{dealId}/move — body { "new_stage_id": "stage-3", "new_position": 0 }. Position 0 puts the card at the top of the column.

curl -X POST "https://api.youraiconnector.com/v1/deals/deal_abc123/move?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "new_stage_id": "stage-3", "new_position": 0 }'

Response (200): { "success": true, "deal_id": "deal_abc123", "stage": "stage-3", "position": 0 }


Delete a deal

DELETE /deals/{dealId} — removes the deal. This cannot be undone.

curl -X DELETE "https://api.youraiconnector.com/v1/deals/deal_abc123?apiKey=YOUR_API_KEY"

Response (200): { "success": true }


Pipelines

Every account has a main pipeline (id: "default"); you can add up to nine more, each with its own stages. Stage ids and trigger tags must be unique across all pipelines on the account, and each pipeline can mark one stage as its won and one as its lost outcome.

List pipelines

GET /pipelines — every pipeline, main one first, each with its stages sorted by position.

curl "https://api.youraiconnector.com/v1/pipelines?apiKey=YOUR_API_KEY"

Response (200):

{
  "success": true,
  "data": {
    "pipelines": [
      {
        "id": "default",
        "name": "Sales",
        "position": 0,
        "is_default": true,
        "settings": { "sync_stage_tags": false },
        "stages": [
          { "id": "stage-1", "name": "New lead", "color": "#3B82F6", "position": 0, "trigger_tag": null },
          { "id": "won", "name": "Won", "color": "#10B981", "position": 1, "outcome": "won" }
        ]
      }
    ]
  }
}

Create a pipeline

POST /pipelines — body { "id"?, "name", "stages"?, "settings"? }. Leave id out to have one generated. Each stage takes the same fields as the Stages dialog: id, name, color, position, optional trigger_tag (a tag path, users/{uid}/tags/{tagId}), default_value, auto_move_after_days + auto_move_to_stage (a stage of the same pipeline) and outcome ("won" or "lost").

curl -X POST "https://api.youraiconnector.com/v1/pipelines?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "reviews",
    "name": "Review requests",
    "stages": [
      { "id": "rv_asked", "name": "Asked", "color": "#3B82F6", "position": 0 },
      { "id": "rv_done", "name": "Review posted", "color": "#10B981", "position": 1, "outcome": "won" }
    ]
  }'

Response (201): { "success": true, "data": { "pipeline": { ... } } }. A stage id or trigger tag already used by another pipeline is a 400 naming that pipeline; an id that already exists is a 409.

Update a pipeline

PUT /pipelines/{pipelineId} — body { "name"?, "stages"?, "settings"? }. stages replaces the whole list, like the Stages dialog. Use default for the main pipeline. The pipeline id itself cannot be changed.

Delete a pipeline

DELETE /pipelines/{pipelineId} — removes an extra pipeline (the main one cannot be deleted). If deals still sit in its stages the call answers 409 with deal_count; add ?delete_deals=true to delete those deals together with the pipeline. This cannot be undone.

Response (204).


Next steps

  • Sales Pipeline — how stages, stage tags, several pipelines and the board work.
  • Tasks API — tasks can be linked to a deal with deal_id.
  • Automations — the Find deals and Find deal steps read the same data inside a workflow.