niiko/developers

CRM v1 current

crm.deal_created

Opens a new deal in the pipeline for a client named by name, with a title, an optional value in USD, an optional stage (by name; without it, the first one) and an optional owner. Does not check for other open deals: it returns how many remain so a duplicate is visible. Does not win or lose it: that is crm.stage_moved.

Last updated

POST /api/v1/actions/crm.deal_created
Key scope
crm.deal_created@1
Workspace permission
api.crm.deal_created off by default
Two permissions, not one

Both are needed: a key with that scope, and the workspace owner having switched the permission on. Holding the key is not enough — they are two decisions made by different people.

Request

fieldtyperules
clientstringrequiredmin 1 · max 200
titlestringrequiredmin 1 · max 200
valueUsdstringoptional^\d+(\.\d{1,2})?$
stagestringoptionalmin 1 · max 120
ownerstringoptionalmin 1 · max 200

Response — output when status is done

fieldtyperules
dealIdstringrequired
clientIdstringrequired
clientNamestringrequired
titlestringrequired
valueUsdstring | nullrequired
stageNamestringrequired
ownerNamestring | nullrequired
openDealsintegerrequired≥ 1

Example

# One request, one idempotency key: retrying with the same key never runs twice.
curl -X POST https://niiko.org/api/v1/actions/crm.deal_created \
  -H "Authorization: Bearer nk_…" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "client": "…",
    "title": "…"
  }'
# 200 → done · 202 → pending_approval (a person signs later) · 4xx → refused, with a named reason

Why it may refuse

Each reason names who can fix it and how. With reason stale, detail.message says what to do.

cliente_no_encontradocliente_ambiguodemasiados_clientesetapa_no_encontradaetapa_cerradapersona_no_encontradapersona_ambiguasin_permiso

In the clients

@vorluno/niiko-sdkniiko.createdDeal()
niiko (Python)niiko.created_deal()
niiko-cliniiko run crm.deal_created
n8n-nodes-niikocrmDealCreated
niiko-mcp-servercrm_deal_created

History