Skip to main content
Tech Titan

API Method Guide

crm.deal.add

Module: CRM (deals)Scope: crm

Direct answer

crm.deal.add creates a deal. Set TITLE, CATEGORY_ID (pipeline), STAGE_ID, CONTACT_ID/COMPANY_ID bindings, OPPORTUNITY (amount), and custom fields; the response returns the new deal ID.

What crm.deal.add does

Creates a deal — a qualified opportunity in a pipeline. Used by integrations that skip or bypass leads: e-commerce orders, booking systems, ERP-originated opportunities, and 'no-lead mode' portals.

Business use cases

  • E-commerce or booking platforms creating deals per order/booking
  • ERP quotations mirrored as CRM deals
  • No-lead-mode capture: qualified inquiries straight to a pipeline
  • Renewal/recurring deal generation from subscription systems
  • Cross-pipeline handover: won sales deal spawning an onboarding deal

Typical fields and parameters

  • TITLEDeal title — include order/reference numbers for list-view scannability
  • CATEGORY_IDPipeline ID (0 = default). Get IDs from crm.category.list. Wrong pipeline = invisible deal
  • STAGE_IDStage within that pipeline — stage IDs are per-category (e.g. C2:NEW); mismatched pairs fail confusingly
  • CONTACT_ID / COMPANY_IDBindings to person/org. Multiple contacts via crm.deal.contact.items.set after creation
  • OPPORTUNITY + CURRENCY_IDAmount and currency; set IS_MANUAL_OPPORTUNITY='Y' if product rows shouldn't overwrite it
  • ASSIGNED_BY_IDResponsible user
  • UF_CRM_*Custom fields — unit reference, order ID, contract type…

Example workflow

  1. Order confirmed in your e-commerce backend
  2. Contact resolved: crm.contact.list by phone/email → found ID, or crm.contact.add
  3. crm.deal.add with CATEGORY_ID for the 'Online Orders' pipeline, CONTACT_ID bound, OPPORTUNITY set
  4. crm.item.productrow.set attaches purchased items
  5. Deal ID stored against the order for status sync-back

Example request

POST .../crm.deal.add.json

{
  "fields": {
    "TITLE": "Order #8842 — Ahmed",
    "CATEGORY_ID": 2,
    "STAGE_ID": "C2:NEW",
    "CONTACT_ID": 512,
    "OPPORTUNITY": 4500,
    "CURRENCY_ID": "AED",
    "ASSIGNED_BY_ID": 7,
    "UF_CRM_ORDER_ID": "8842"
  },
  "params": { "REGISTER_SONET_EVENT": "Y" }
}

Example response

{ "result": 3120, "time": { ... } }
// "result" is the new deal ID.

Field mapping notes

  • STAGE_ID format is C{categoryId}:{stageCode} for non-default pipelines — 'NEW' alone lands in the default pipeline's stage
  • Bind contacts at creation where possible; orphan deals break reporting and communication matching
  • OPPORTUNITY is overwritten by product-row totals unless IS_MANUAL_OPPORTUNITY is 'Y'
  • Keep the external system's ID in a custom field — it is your sync key forever

Security notes

  • Deals carry commercial data; scope the integration account's pipeline visibility deliberately
  • Validate amounts server-side — never trust client-submitted OPPORTUNITY values

Common errors

  • Deal appears in wrong pipelineSTAGE_ID/CATEGORY_ID mismatch — fetch valid pairs from crm.category.list + crm.status.list
  • Product rows overwrote the amountSet IS_MANUAL_OPPORTUNITY='Y' or set amount after rows
  • 'Access denied' on a specific pipelineThe integration user lacks rights to that category — permissions are per-pipeline
  • Duplicate deals per orderRetry without idempotency — check for existing UF_CRM_ORDER_ID before adding

Production implementation tips

  • Search-by-external-ID before create makes your integration safely re-runnable
  • Batch deal + product rows + timeline comment into one batch call
  • New-deal automations (notifications, tasks) fire on API creation too — design rules knowing half your deals arrive via API

Webhook or OAuth app?

Webhook for internal one-way flows; OAuth app for two-way order/deal sync where token hygiene and user-independence matter over years.

Full decision guide: webhook vs OAuth app in Bitrix24.

When to use a queue worker

Order bursts (sales, campaigns) need queued creation. Serialize per-customer to keep contact resolution race-free.

How Tech Titan can help

Tech Titan builds production Bitrix24 integrations around crm.deal.add and its siblings — with authentication, field mapping, queue workers, retry logic, duplicate handling, and structured logs as standard. If this method is on your critical path, bring the requirement to a free audit call and leave with an architecture sketch.

Frequently asked questions

How do I create a deal in Bitrix24 using crm.deal.add?

POST a fields object with TITLE, CATEGORY_ID, STAGE_ID, bindings, and amount to crm.deal.add. The response returns the deal ID — see the example.

How do I attach a contact to a deal via API?

Set CONTACT_ID at creation, or use crm.deal.contact.add / crm.deal.contact.items.set for multiple contacts after creation.

How do I add products to the deal?

After creation, call crm.deal.productrows.set (classic) or crm.item.productrow.* (universal) with the row array. Totals update OPPORTUNITY unless manual mode is set.

Need crm.deal.add working in production?

Bring your integration to a free audit call — you'll leave with an architecture sketch and an honest scope, whether or not you engage us.