A deal always sits in a stage of a pipeline and belongs to a contact. To open one through the API, read the pipelines to find the stage ID, then create the deal. The shared rules for keys, JSON and limits are in REST API, and the way deals work in the app is explained in Deals and pipelines.
List pipelines and stages
GET /pipelines
curl https://rutbacrm.com/api/v1/pipelines \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
{
"data": [
{
"id": "PIPELINE_ID",
"name": "Sales",
"stages": [
{"id": "STAGE_ID", "name": "New", "position": 1},
{"id": "STAGE_ID_2", "name": "Qualified", "position": 2}
]
}
]
}
| Field | Meaning |
|---|---|
id, name |
The pipeline |
stages |
Its active stages in board order |
stages[].position |
The stage's place on the board, starting at 1 |
Only active pipelines and stages are listed, oldest pipeline first: up to 20 pipelines and 12 stages in each. Stage IDs do not change when a stage is renamed, so you can store them in your system's settings.
Open a deal
POST /deals
Needs a Read and write key whose creator is a member, administrator or owner.
| Field | Required | Rules |
|---|---|---|
contact_id |
Yes | The UUID of a contact in your company |
stage_id |
Yes | The UUID of an active stage. The deal goes into that stage's pipeline |
title |
Yes | Up to 160 characters |
amount |
No | A string such as "1250.50": digits, an optional point and up to two decimals, at most 13 digits before the point. Thousands commas are accepted only in the form "1,250.50" |
currency |
With amount |
USD, EUR, GBP, TRY, SAR or AED. Send both amount and currency, or neither |
next_step |
No | Up to 200 characters |
next_step_on |
No | A date, YYYY-MM-DD |
Other fields are ignored. Deals created through the API have no owner and no expected close date. Set those in the app.
curl -X POST https://rutbacrm.com/api/v1/deals \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"contact_id": "CONTACT_ID", "stage_id": "STAGE_ID", "title": "Espresso machine for the new branch", "amount": "1250.50", "currency": "SAR", "next_step": "Send the quote", "next_step_on": "2026-11-12"}'
A new deal returns 201:
{
"data": {
"id": "DEAL_ID"
}
}
The deal opens with the status open, enters the chosen stage now, and shows the person who created the key as its creator in its history.
Responses
| Status | When |
|---|---|
201 |
The deal was created |
404 |
The contact or the stage does not exist in your company, or the stage or its pipeline is archived |
422 |
contact_id or stage_id is missing or not a UUID, with no errors object |
422 |
The contact is archived, with the error under contact_id |
422 |
A field is invalid, with an errors object. For example, an amount sent as a JSON number, an amount without a currency, or a date in another format |
403 |
The key is read only, or its creator is a viewer |
An amount sent as a number, such as 1250.5, is refused. Always send it as a string.
Good to know
- Each call creates a new deal. If a request times out, check the contact's deals in the app before you retry, or you may open the same deal twice.
- An archived, merged or erased contact cannot receive a new deal.
- Deals cannot be moved, won, lost or edited through the API. When a deal is won in the app, the webhook event A deal is won tells your system.
Last updated 2026-11-08