Opens one deal from the signal that prompted it. The card’s signal* fields are copied from that signal here and never refreshed afterwards.
Idempotent by signal. A unique index refuses a second deal for the same signal, and this answers 200 with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers 201, which is how a caller tells the two apart.
A workspace API key, created in workspace settings and sent as Authorization: Bearer op_live_…. Session cookies are not accepted. Scopes: signals:read, accounts:read, listeners:read, listeners:analyse, pipeline:read, pipeline:write, collections:write, export:read.
Body
application/json
Which signal to open a deal from, and where to put it.
Clerk user id to assign it to. Unassigned is a legitimate state: a shared triage board is a real way to work.
Maximum string length: 120
Response
A deal already existed for this signal; it is returned unchanged and nothing was written.
One deal on the board. Attached to a signal, never to an account: an entry that could do either would count one deal twice, once against the signal and once against the company, and nobody would notice for a quarter.
The signal* fields are a snapshot copied when the deal was made, not a mirror. If the signal is later re-classified the card still says what the lead looked like when somebody decided to act on it, which explains the decision rather than second-guessing it. They are absent on deals created before each field existed.
First time it reached each stage. Kept per stage rather than as one timestamp so cycle time survives a deal moving backwards, which real deals do. Sparse: stages it has never reached are absent.
A person at the other end of a deal. On the deal rather than on the account, because most market signals resolve no accountKey at all. Every field is optional: a name with no email is a better record than no record.
When it reached won or lost. Removed again if it reopens.
Was this page helpful?
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Open Pulse","description":"Open Pulse finds public conversations that are evidence somebody has a budgeted problem, and scores each one against what you sell.","colors":{"primary":"#446317","light":"#C6E868","dark":"#446317"},"logo":{"light":"https://mintcdn.com/open-pulse/2lhu05m2dSiIFlof/logo/light.svg?fit=max\u0026auto=format\u0026n=2lhu05m2dSiIFlof\u0026q=85\u0026s=a403a5531b58270dadb02f1862164683","dark":"https://mintcdn.com/open-pulse/2lhu05m2dSiIFlof/logo/dark.svg?fit=max\u0026auto=format\u0026n=2lhu05m2dSiIFlof\u0026q=85\u0026s=518fb339322cbf15840dff18d8da3847"},"favicon":"https://mintcdn.com/open-pulse/P8LbHWHUpEv-R7cz/favicon.svg?fit=max\u0026auto=format\u0026n=P8LbHWHUpEv-R7cz\u0026q=85\u0026s=4f377ad25662c68808d611467995875a","navbar":{"links":[{"href":"https://openpulse.cloud/sign-in","label":"Sign in"}],"primary":{"type":"button","label":"Get started","href":"https://openpulse.cloud/pricing"}},"footer":{"links":[{"header":"Open Pulse","items":[{"label":"Product","href":"https://openpulse.cloud"},{"label":"Pricing","href":"https://openpulse.cloud/pricing"},{"label":"Developers","href":"https://openpulse.cloud/developers"}]},{"header":"Follow","items":[{"label":"TikTok","href":"https://www.tiktok.com/@getopenpulse"},{"label":"X","href":"https://x.com/getopenpulse"},{"label":"Instagram","href":"https://www.instagram.com/getopenpulse"}]}]},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"open-pulse","hasAudioNarration":false,"actualSubdomain":"open-pulse","customDomains":["docs.openpulse.cloud"],"gitSource":{"type":"github","owner":"optiqlabs","repo":"open-pulse","deployBranch":"develop","contentDirectory":"apps/docs","isPrivate":true,"mountPath":"","label":""},"chroma":{"latestBuiltDeploymentHistoryId":"6ae17d044eb6f5188cc094f4","collectionId":"88fa9485-d841-4c17-9d70-2fa1eaff8c23","liveDeploymentHistoryId":"6ae17d044eb6f5188cc094f4","schemaVersion":"v3"},"feedback":{"thumbs":true},"entitlements":{"AI_CHAT":{"status":"DISABLED"},"WEB_MCP":{"status":"DISABLED"},"NARRATION":{"status":"DISABLED"}},"buildId":"6ae17d044eb6f5188cc094f4","clientVersion":"0.0.4076","searchFilterCounts":[{"language":"default","tag":"Guides","count":22},{"language":"default","tag":"API Reference","count":20},{"language":"default","tag":"Integrations","count":5},{"language":"default","tag":"Pipeline","count":5},{"language":"default","tag":"Selling Surfaces","count":4},{"language":"default","tag":"Results","count":4},{"language":"default","tag":"Working Leads","count":3},{"language":"default","tag":"Delivering \u0026 Managing","count":3},{"language":"default","tag":"Listeners \u0026 Runs","count":3},{"language":"default","tag":"Exports","count":3}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/pipeline/add-a-deal","slug":"/api-reference/pipeline/add-a-deal","pageMetadata":{"title":"Add a deal","description":"Opens one deal from the signal that prompted it. The card's `signal*` fields are copied from that signal here and never refreshed afterwards.\n\n**Idempotent by signal.** A unique index refuses a second deal for the same signal, and this answers `200` with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers `201`, which is how a caller tells the two apart.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/pipeline","href":"/api-reference/pipeline/add-a-deal","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n strong: \"strong\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Opens one deal from the signal that prompted it. The card’s \", _jsx(_components.code, {\n children: \"signal*\"\n }), \" fields are copied from that signal here and never refreshed afterwards.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"Idempotent by signal.\"\n }), \" A unique index refuses a second deal for the same signal, and this answers \", _jsx(_components.code, {\n children: \"200\"\n }), \" with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers \", _jsx(_components.code, {\n children: \"201\"\n }), \", which is how a caller tells the two apart.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Add a deal","description":"Opens one deal from the signal that prompted it. The card's `signal*` fields are copied from that signal here and never refreshed afterwards.\n\n**Idempotent by signal.** A unique index refuses a second deal for the same signal, and this answers `200` with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers `201`, which is how a caller tells the two apart.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/pipeline","href":"/api-reference/pipeline/add-a-deal","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"postV1Pipeline","summary":"Add a deal","description":"Opens one deal from the signal that prompted it. The card's `signal*` fields are copied from that signal here and never refreshed afterwards.\n\n**Idempotent by signal.** A unique index refuses a second deal for the same signal, and this answers `200` with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers `201`, which is how a caller tells the two apart.","tags":["pipeline"],"security":["e7ccb2b5-09fc-4eec-bdd4-a7f0bbd5800a"],"parameters":[],"requestBody":"0588c102-7762-4a51-a1df-0f5b31d59de5","responses":{"200":"09f9c7b7-9b42-4fa0-97af-65934cb271e7","201":"fed8a109-ddf7-45b3-89d5-285e3cae891b","400":"1183f828-c182-4470-a2ae-5ce0b711dc23","401":"0e9a9e9e-bf9d-43fd-8ebb-6f18e10c0e9d","402":"37bea83f-7885-4362-ad97-672b9409e34e","403":"16fbd5b4-bee5-48ef-a4b0-b557b4d5d5ff","404":"d73e9173-0e9d-4d2c-accf-f2b7a9034f3d","429":"826ae64a-60af-4665-95b6-f2d29cb04ad2"},"method":"post","type":"path","servers":["15b4899c-a482-4812-8f0c-fad24a079ee3"],"path":"/v1/pipeline","baseUrlOptions":["https://api.openpulse.cloud"],"title":"Add a deal","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"description":"Which signal to open a deal from, and where to put it.","content":{"application/json":{"schema":{"type":"object","required":["signalId"],"properties":{"signalId":{"type":"string","description":"The signal this deal comes from. Must exist in this workspace.","minLength":1,"maxLength":120,"isRequired":true,"uniqueKey":"signalId","typeLabel":"string"},"stage":{"type":"string","enum":["new","contacted","meeting","won","lost"],"default":"new","description":"Where it lands on the board.","uniqueKey":"stage","typeLabel":"enum\u003cstring>"},"ownerUserId":{"type":"string","description":"Clerk user id to assign it to. Unassigned is a legitimate state: a shared triage board is a real way to work.","maxLength":120,"uniqueKey":"ownerUserId","typeLabel":"string"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"signalId":"\u003cstring>","stage":"new","ownerUserId":"\u003cstring>"}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"09f9c7b7-9b42-4fa0-97af-65934cb271e7":{"description":"A deal already existed for this signal; it is returned unchanged and nothing was written.","content":{"application/json":{"schema":{"type":"object","description":"One deal on the board. **Attached to a signal, never to an account**: an entry that could do either would count one deal twice, once against the signal and once against the company, and nobody would notice for a quarter.\n\nThe `signal*` fields are a **snapshot copied when the deal was made**, not a mirror. If the signal is later re-classified the card still says what the lead looked like when somebody decided to act on it, which explains the decision rather than second-guessing it. They are absent on deals created before each field existed.","required":["id","orgId","signalId","stage","enteredStageAt","stageFirstAt","createdAt","createdBy","updatedAt"],"properties":{"id":{"type":"string","description":"Stable identifier. What `PATCH /v1/pipeline/{id}` takes.","isRequired":true,"uniqueKey":"id","typeLabel":"string"},"orgId":{"type":"string","description":"The workspace this belongs to (`org_…`).","isRequired":true,"uniqueKey":"orgId","typeLabel":"string"},"signalId":{"type":"string","description":"The signal this came from. Unique per workspace — one deal per signal.","isRequired":true,"uniqueKey":"signalId","typeLabel":"string"},"stage":{"type":"string","enum":["new","contacted","meeting","won","lost"],"description":"Where it is on the board.","isRequired":true,"uniqueKey":"stage","typeLabel":"enum\u003cstring>"},"enteredStageAt":{"type":"string","format":"date-time","description":"When it entered the stage it is in now.","isRequired":true,"uniqueKey":"enteredStageAt","typeLabel":"string\u003cdate-time>"},"stageFirstAt":{"type":"object","description":"First time it reached each stage. Kept per stage rather than as one timestamp so cycle time survives a deal moving backwards, which real deals do. Sparse: stages it has never reached are absent.","propertyNames":{"enum":["new","contacted","meeting","won","lost"]},"additionalProperties":{"type":"string","format":"date-time","uniqueKey":"stageFirstAt.additionalProperties","typeLabel":"string\u003cdate-time>"},"isRequired":true,"uniqueKey":"stageFirstAt","typeLabel":"object"},"createdAt":{"type":"string","format":"date-time","description":"When the deal was opened.","isRequired":true,"uniqueKey":"createdAt","typeLabel":"string\u003cdate-time>"},"createdBy":{"type":"string","description":"Clerk user id of whoever opened it.","isRequired":true,"uniqueKey":"createdBy","typeLabel":"string"},"updatedAt":{"type":"string","format":"date-time","description":"When the row last changed. The pagination sort key.","isRequired":true,"uniqueKey":"updatedAt","typeLabel":"string\u003cdate-time>"},"signalTitle":{"type":"string","description":"The signal's title at the moment the deal was made.","uniqueKey":"signalTitle","typeLabel":"string"},"signalClassification":{"type":"string","enum":["high_intent","evaluating","relevant","competitor","content","strong_match","worth_a_look","stretch","mismatch","stale","hiring_now","expanding","replacing","adjacent","switching","frustrated","comparing","praise","pain_confirmed","at_risk","healthy","noise"],"description":"What the signal was judged to be then.","uniqueKey":"signalClassification","typeLabel":"enum\u003cstring>"},"signalScore":{"type":"integer","description":"Its `relevanceScore` then.","minimum":0,"maximum":100,"uniqueKey":"signalScore","typeLabel":"integer"},"signalCategory":{"type":"string","enum":["direct_intent","hire_vs_buy","competitor_pain","growth","funding","procurement","construction","regulatory","operational_pain","tech_change","leadership_change","real_estate","new_business","cx_failure","missing_capability","incident"],"description":"Its category then.","uniqueKey":"signalCategory","typeLabel":"enum\u003cstring>"},"signalUrgency":{"type":"string","enum":["low","medium","high","immediate"],"description":"Its urgency then.","uniqueKey":"signalUrgency","typeLabel":"enum\u003cstring>"},"signalUrl":{"type":"string","description":"Link to the post itself.","format":"uri","uniqueKey":"signalUrl","typeLabel":"string\u003curi>"},"signalSource":{"type":"string","enum":["x","linkedin","facebook","reddit","hackernews","linkedin_jobs","indeed","ashby","greenhouse","lever","google_reviews","g2","trustpilot","youtube","vendor_community"],"description":"Which platform it came from.","uniqueKey":"signalSource","typeLabel":"enum\u003cstring>"},"signalSummary":{"type":"string","description":"The post's text, copied from the signal's `excerpt`.","uniqueKey":"signalSummary","typeLabel":"string"},"accountKey":{"type":"string","description":"Denormalised so revenue can be grouped by company without a join.","uniqueKey":"accountKey","typeLabel":"string"},"ownerUserId":{"type":"string","description":"Clerk user id of whoever owns it. Unassigned is a legitimate state.","uniqueKey":"ownerUserId","typeLabel":"string"},"dealValueMinor":{"type":"integer","description":"Value in **minor units**, as an integer — pence, cents. Never a float: a revenue total out by a penny is a revenue total nobody trusts.","minimum":0,"uniqueKey":"dealValueMinor","typeLabel":"integer"},"currency":{"type":"string","description":"ISO 4217, upper-cased. Stored beside the value rather than assumed.","minLength":3,"maxLength":3,"uniqueKey":"currency","typeLabel":"string"},"lostReason":{"type":"string","description":"Why it was lost, when somebody said.","uniqueKey":"lostReason","typeLabel":"string"},"contact":{"type":"object","description":"A person at the other end of a deal. On the **deal** rather than on the account, because most market signals resolve no `accountKey` at all. Every field is optional: a name with no email is a better record than no record.","properties":{"name":{"type":"string","description":"Their name.","uniqueKey":"contact.name","typeLabel":"string"},"role":{"type":"string","description":"Their job title.","uniqueKey":"contact.role","typeLabel":"string"},"email":{"type":"string","description":"Their email address.","format":"email","uniqueKey":"contact.email","typeLabel":"string\u003cemail>"},"phone":{"type":"string","description":"Their phone number, as somebody typed it. A plain string and not a parsed number: extensions and \"ask for Dave on the mobile\" are things people type into this box, and refusing them loses the contact to enforce a format nothing reads programmatically.","uniqueKey":"contact.phone","typeLabel":"string"}},"uniqueKey":"contact","typeLabel":"object"},"closedAt":{"type":"string","format":"date-time","description":"When it reached `won` or `lost`. Removed again if it reopens.","uniqueKey":"closedAt","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"id":"\u003cstring>","orgId":"\u003cstring>","signalId":"\u003cstring>","stage":"new","enteredStageAt":"2023-11-07T05:31:56Z","stageFirstAt":{},"createdAt":"2023-11-07T05:31:56Z","createdBy":"\u003cstring>","updatedAt":"2023-11-07T05:31:56Z","signalTitle":"\u003cstring>","signalClassification":"high_intent","signalScore":50,"signalCategory":"direct_intent","signalUrgency":"low","signalUrl":"\u003cstring>","signalSource":"x","signalSummary":"\u003cstring>","accountKey":"\u003cstring>","ownerUserId":"\u003cstring>","dealValueMinor":1,"currency":"\u003cstring>","lostReason":"\u003cstring>","contact":{"name":"\u003cstring>","role":"\u003cstring>","email":"jsmith@example.com","phone":"\u003cstring>"},"closedAt":"2023-11-07T05:31:56Z"}}},"exampleType":"generated"}},"exampleType":"generated"},"fed8a109-ddf7-45b3-89d5-285e3cae891b":{"description":"The deal, as created.","content":{"application/json":{"schema":{"type":"object","description":"One deal on the board. **Attached to a signal, never to an account**: an entry that could do either would count one deal twice, once against the signal and once against the company, and nobody would notice for a quarter.\n\nThe `signal*` fields are a **snapshot copied when the deal was made**, not a mirror. If the signal is later re-classified the card still says what the lead looked like when somebody decided to act on it, which explains the decision rather than second-guessing it. They are absent on deals created before each field existed.","required":["id","orgId","signalId","stage","enteredStageAt","stageFirstAt","createdAt","createdBy","updatedAt"],"properties":{"id":{"type":"string","description":"Stable identifier. What `PATCH /v1/pipeline/{id}` takes.","isRequired":true,"uniqueKey":"id","typeLabel":"string"},"orgId":{"type":"string","description":"The workspace this belongs to (`org_…`).","isRequired":true,"uniqueKey":"orgId","typeLabel":"string"},"signalId":{"type":"string","description":"The signal this came from. Unique per workspace — one deal per signal.","isRequired":true,"uniqueKey":"signalId","typeLabel":"string"},"stage":{"type":"string","enum":["new","contacted","meeting","won","lost"],"description":"Where it is on the board.","isRequired":true,"uniqueKey":"stage","typeLabel":"enum\u003cstring>"},"enteredStageAt":{"type":"string","format":"date-time","description":"When it entered the stage it is in now.","isRequired":true,"uniqueKey":"enteredStageAt","typeLabel":"string\u003cdate-time>"},"stageFirstAt":{"type":"object","description":"First time it reached each stage. Kept per stage rather than as one timestamp so cycle time survives a deal moving backwards, which real deals do. Sparse: stages it has never reached are absent.","propertyNames":{"enum":["new","contacted","meeting","won","lost"]},"additionalProperties":{"type":"string","format":"date-time","uniqueKey":"stageFirstAt.additionalProperties","typeLabel":"string\u003cdate-time>"},"isRequired":true,"uniqueKey":"stageFirstAt","typeLabel":"object"},"createdAt":{"type":"string","format":"date-time","description":"When the deal was opened.","isRequired":true,"uniqueKey":"createdAt","typeLabel":"string\u003cdate-time>"},"createdBy":{"type":"string","description":"Clerk user id of whoever opened it.","isRequired":true,"uniqueKey":"createdBy","typeLabel":"string"},"updatedAt":{"type":"string","format":"date-time","description":"When the row last changed. The pagination sort key.","isRequired":true,"uniqueKey":"updatedAt","typeLabel":"string\u003cdate-time>"},"signalTitle":{"type":"string","description":"The signal's title at the moment the deal was made.","uniqueKey":"signalTitle","typeLabel":"string"},"signalClassification":{"type":"string","enum":["high_intent","evaluating","relevant","competitor","content","strong_match","worth_a_look","stretch","mismatch","stale","hiring_now","expanding","replacing","adjacent","switching","frustrated","comparing","praise","pain_confirmed","at_risk","healthy","noise"],"description":"What the signal was judged to be then.","uniqueKey":"signalClassification","typeLabel":"enum\u003cstring>"},"signalScore":{"type":"integer","description":"Its `relevanceScore` then.","minimum":0,"maximum":100,"uniqueKey":"signalScore","typeLabel":"integer"},"signalCategory":{"type":"string","enum":["direct_intent","hire_vs_buy","competitor_pain","growth","funding","procurement","construction","regulatory","operational_pain","tech_change","leadership_change","real_estate","new_business","cx_failure","missing_capability","incident"],"description":"Its category then.","uniqueKey":"signalCategory","typeLabel":"enum\u003cstring>"},"signalUrgency":{"type":"string","enum":["low","medium","high","immediate"],"description":"Its urgency then.","uniqueKey":"signalUrgency","typeLabel":"enum\u003cstring>"},"signalUrl":{"type":"string","description":"Link to the post itself.","format":"uri","uniqueKey":"signalUrl","typeLabel":"string\u003curi>"},"signalSource":{"type":"string","enum":["x","linkedin","facebook","reddit","hackernews","linkedin_jobs","indeed","ashby","greenhouse","lever","google_reviews","g2","trustpilot","youtube","vendor_community"],"description":"Which platform it came from.","uniqueKey":"signalSource","typeLabel":"enum\u003cstring>"},"signalSummary":{"type":"string","description":"The post's text, copied from the signal's `excerpt`.","uniqueKey":"signalSummary","typeLabel":"string"},"accountKey":{"type":"string","description":"Denormalised so revenue can be grouped by company without a join.","uniqueKey":"accountKey","typeLabel":"string"},"ownerUserId":{"type":"string","description":"Clerk user id of whoever owns it. Unassigned is a legitimate state.","uniqueKey":"ownerUserId","typeLabel":"string"},"dealValueMinor":{"type":"integer","description":"Value in **minor units**, as an integer — pence, cents. Never a float: a revenue total out by a penny is a revenue total nobody trusts.","minimum":0,"uniqueKey":"dealValueMinor","typeLabel":"integer"},"currency":{"type":"string","description":"ISO 4217, upper-cased. Stored beside the value rather than assumed.","minLength":3,"maxLength":3,"uniqueKey":"currency","typeLabel":"string"},"lostReason":{"type":"string","description":"Why it was lost, when somebody said.","uniqueKey":"lostReason","typeLabel":"string"},"contact":{"type":"object","description":"A person at the other end of a deal. On the **deal** rather than on the account, because most market signals resolve no `accountKey` at all. Every field is optional: a name with no email is a better record than no record.","properties":{"name":{"type":"string","description":"Their name.","uniqueKey":"contact.name","typeLabel":"string"},"role":{"type":"string","description":"Their job title.","uniqueKey":"contact.role","typeLabel":"string"},"email":{"type":"string","description":"Their email address.","format":"email","uniqueKey":"contact.email","typeLabel":"string\u003cemail>"},"phone":{"type":"string","description":"Their phone number, as somebody typed it. A plain string and not a parsed number: extensions and \"ask for Dave on the mobile\" are things people type into this box, and refusing them loses the contact to enforce a format nothing reads programmatically.","uniqueKey":"contact.phone","typeLabel":"string"}},"uniqueKey":"contact","typeLabel":"object"},"closedAt":{"type":"string","format":"date-time","description":"When it reached `won` or `lost`. Removed again if it reopens.","uniqueKey":"closedAt","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"id":"\u003cstring>","orgId":"\u003cstring>","signalId":"\u003cstring>","stage":"new","enteredStageAt":"2023-11-07T05:31:56Z","stageFirstAt":{},"createdAt":"2023-11-07T05:31:56Z","createdBy":"\u003cstring>","updatedAt":"2023-11-07T05:31:56Z","signalTitle":"\u003cstring>","signalClassification":"high_intent","signalScore":50,"signalCategory":"direct_intent","signalUrgency":"low","signalUrl":"\u003cstring>","signalSource":"x","signalSummary":"\u003cstring>","accountKey":"\u003cstring>","ownerUserId":"\u003cstring>","dealValueMinor":1,"currency":"\u003cstring>","lostReason":"\u003cstring>","contact":{"name":"\u003cstring>","role":"\u003cstring>","email":"jsmith@example.com","phone":"\u003cstring>"},"closedAt":"2023-11-07T05:31:56Z"}}},"exampleType":"generated"}},"exampleType":"generated"},"1183f828-c182-4470-a2ae-5ce0b711dc23":{"description":"The body is missing `signalId` or carries an unknown `stage`.","content":{"application/json":{"schema":{"type":"object","description":"What went wrong, in a shape every failing route shares.","required":["message"],"properties":{"message":{"type":"string","description":"Human-readable explanation, safe to show a user.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable error code, when the failure has one worth branching on. `website_unreadable` and `forbidden` are the two a caller acts on.","uniqueKey":"code","typeLabel":"string"},"detail":{"description":"Validator output on a 400, as an array of issues naming the offending field. Diagnostic only: the shape comes from the validation library and is not part of the contract.","uniqueKey":"detail","typeLabel":"any"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"\u003cstring>","code":"\u003cstring>","detail":"\u003cunknown>"}}},"exampleType":"generated"}},"exampleType":"generated"},"0e9a9e9e-bf9d-43fd-8ebb-6f18e10c0e9d":{"description":"The key is missing, malformed, expired or revoked.","content":{"application/json":{"schema":{"type":"object","description":"What went wrong, in a shape every failing route shares.","required":["message"],"properties":{"message":{"type":"string","description":"Human-readable explanation, safe to show a user.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable error code, when the failure has one worth branching on. `website_unreadable` and `forbidden` are the two a caller acts on.","uniqueKey":"code","typeLabel":"string"},"detail":{"description":"Validator output on a 400, as an array of issues naming the offending field. Diagnostic only: the shape comes from the validation library and is not part of the contract.","uniqueKey":"detail","typeLabel":"any"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"\u003cstring>","code":"\u003cstring>","detail":"\u003cunknown>"}}},"exampleType":"generated"}},"exampleType":"generated"},"37bea83f-7885-4362-ad97-672b9409e34e":{"description":"The workspace's plan does not include the pipeline. The body names the plan it holds and the entitlement it is missing. **Not a 403**: the key is fine, the subscription is not, and widening the key will not help.","content":{"application/json":{"schema":{"type":"object","description":"A refusal about entitlement: the workspace's plan does not include this. The fix is a subscription change, never a change to the key.","required":["message","code","plan"],"properties":{"message":{"type":"string","description":"Human-readable explanation, safe to show a user. Names the plan where one would help.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"code":{"type":"string","enum":["plan_required","listener_limit_reached","webhook_limit_reached","cadence_not_allowed","competitor_access_required","competitor_limit_reached","competitor_collect_cooldown","analyse_quota_reached","run_quota_reached","source_not_allowed","custom_scoring_access_required","collection_limit_reached","notes_access_required","account_access_required","territory_access_required","pipeline_access_required","assignment_access_required","export_quota_reached","crm_export_access_required","urgency_alert_access_required","draft_quota_reached","api_key_limit_reached","content_channel_access_required","image_draw_limit_reached","refinement_limit_reached","content_quota_reached"],"description":"Which entitlement was missing. Branch on this rather than on `message`.","isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"},"plan":{"type":"string","enum":["op_go","op_growth","op_pro","op_enterprise","none"],"description":"What the workspace holds today. `none` means no subscription.","isRequired":true,"uniqueKey":"plan","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"\u003cstring>","code":"plan_required","plan":"op_go"}}},"exampleType":"generated"}},"exampleType":"generated"},"16fbd5b4-bee5-48ef-a4b0-b557b4d5d5ff":{"description":"The key lacks the `pipeline:write` scope.","content":{"application/json":{"schema":{"type":"object","description":"What went wrong, in a shape every failing route shares.","required":["message"],"properties":{"message":{"type":"string","description":"Human-readable explanation, safe to show a user.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable error code, when the failure has one worth branching on. `website_unreadable` and `forbidden` are the two a caller acts on.","uniqueKey":"code","typeLabel":"string"},"detail":{"description":"Validator output on a 400, as an array of issues naming the offending field. Diagnostic only: the shape comes from the validation library and is not part of the contract.","uniqueKey":"detail","typeLabel":"any"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"\u003cstring>","code":"\u003cstring>","detail":"\u003cunknown>"}}},"exampleType":"generated"}},"exampleType":"generated"},"d73e9173-0e9d-4d2c-accf-f2b7a9034f3d":{"description":"No signal with that id in this workspace.","content":{"application/json":{"schema":{"type":"object","description":"What went wrong, in a shape every failing route shares.","required":["message"],"properties":{"message":{"type":"string","description":"Human-readable explanation, safe to show a user.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable error code, when the failure has one worth branching on. `website_unreadable` and `forbidden` are the two a caller acts on.","uniqueKey":"code","typeLabel":"string"},"detail":{"description":"Validator output on a 400, as an array of issues naming the offending field. Diagnostic only: the shape comes from the validation library and is not part of the contract.","uniqueKey":"detail","typeLabel":"any"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"\u003cstring>","code":"\u003cstring>","detail":"\u003cunknown>"}}},"exampleType":"generated"}},"exampleType":"generated"},"826ae64a-60af-4665-95b6-f2d29cb04ad2":{"description":"Too many requests from this key. `Retry-After` carries the seconds to wait.","content":{"application/json":{"schema":{"type":"object","description":"What went wrong, in a shape every failing route shares.","required":["message"],"properties":{"message":{"type":"string","description":"Human-readable explanation, safe to show a user.","isRequired":true,"uniqueKey":"message","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable error code, when the failure has one worth branching on. `website_unreadable` and `forbidden` are the two a caller acts on.","uniqueKey":"code","typeLabel":"string"},"detail":{"description":"Validator output on a 400, as an array of issues naming the offending field. Diagnostic only: the shape comes from the validation library and is not part of the contract.","uniqueKey":"detail","typeLabel":"any"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"message":"\u003cstring>","code":"\u003cstring>","detail":"\u003cunknown>"}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"e7ccb2b5-09fc-4eec-bdd4-a7f0bbd5800a":{"apiKey":{"type":"http","scheme":"bearer","description":"A workspace API key, created in workspace settings and sent as `Authorization: Bearer op_live_…`. Session cookies are not accepted. Scopes: signals:read, accounts:read, listeners:read, listeners:analyse, pipeline:read, pipeline:write, collections:write, export:read.","scopes":["pipeline:write"],"schemeName":"apiKey"}}},"servers":{"15b4899c-a482-4812-8f0c-fad24a079ee3":{"url":"https://api.openpulse.cloud","description":"Production"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"A workspace API key, created in workspace settings and sent as `Authorization: Bearer op_live_…`. Session cookies are not accepted. Scopes: signals:read, accounts:read, listeners:read, listeners:analyse, pipeline:read, pipeline:write, collections:write, export:read.","scopes":["pipeline:write"],"schemeName":"apiKey"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"A workspace API key, created in workspace settings and sent as `Authorization: Bearer op_live_…`. Session cookies are not accepted. Scopes: signals:read, accounts:read, listeners:read, listeners:analyse, pipeline:read, pipeline:write, collections:write, export:read.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"apiKey","name":"Authorization"}],"title":"apiKey"}]},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"open-pulse","siteName":"Open Pulse","title":"Add a deal - Open Pulse","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-27T06:52:28.510Z","originalFileLocation":"api-reference/pipeline/add-a-deal.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Opens one deal from the signal that prompted it. The card\u0026#x27;s signal* fields are copied from that signal here and never refreshed afterwards. Idempotent by signal. A unique index refuses a second deal for the same signal, and this answers 200 with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers 201, which is how a caller tells the two apart.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Open Pulse\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Add a deal - Open Pulse\">\u003cmeta data-mint-head property=\"og:description\" content=\"Opens one deal from the signal that prompted it. The card\u0026#x27;s signal* fields are copied from that signal here and never refreshed afterwards. Idempotent by signal. A unique index refuses a second deal for the same signal, and this answers 200 with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers 201, which is how a caller tells the two apart.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Open Pulse\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://open-pulse.mintlify.site/_mintlify/api/og/v2?division=Pipeline\u0026amp;title=Add+a+deal\u0026amp;description=Opens+one+deal+from+the+signal+that+prompted+it.+The+card%27s+%60signal*%60+fields+are+copied+from+that+signal+here+and+never+refreshed+afterwards.%0A%0A**Idempotent+by+s\u0026amp;theme=d63bc05a3d20cd1eea42e14a\u0026amp;signature=1e0aacb7c607da137e721277719e78ce28dd9f2abd25cba3fb9299fda739adfa\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Add a deal - Open Pulse\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Opens one deal from the signal that prompted it. The card\u0026#x27;s signal* fields are copied from that signal here and never refreshed afterwards. Idempotent by signal. A unique index refuses a second deal for the same signal, and this answers 200 with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers 201, which is how a caller tells the two apart.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://open-pulse.mintlify.site/_mintlify/api/og/v2?division=Pipeline\u0026amp;title=Add+a+deal\u0026amp;description=Opens+one+deal+from+the+signal+that+prompted+it.+The+card%27s+%60signal*%60+fields+are+copied+from+that+signal+here+and+never+refreshed+afterwards.%0A%0A**Idempotent+by+s\u0026amp;theme=d63bc05a3d20cd1eea42e14a\u0026amp;signature=1e0aacb7c607da137e721277719e78ce28dd9f2abd25cba3fb9299fda739adfa\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/open-pulse/_XSUl-ciJBzq3c0r/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Open Pulse\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#446317\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/pipeline/add-a-deal.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.openpulse.cloud/#organization\",\"name\":\"Open Pulse\",\"url\":\"https://docs.openpulse.cloud\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/open-pulse/2lhu05m2dSiIFlof/logo/light.svg?fit=max\u0026auto=format\u0026n=2lhu05m2dSiIFlof\u0026q=85\u0026s=a403a5531b58270dadb02f1862164683\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.openpulse.cloud#website\",\"name\":\"Open Pulse\",\"url\":\"https://docs.openpulse.cloud\",\"publisher\":{\"@id\":\"https://docs.openpulse.cloud/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal#webpage\",\"url\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal\",\"name\":\"Add a deal\",\"description\":\"Opens one deal from the signal that prompted it. The card's signal* fields are copied from that signal here and never refreshed afterwards. Idempotent by signal. A unique index refuses a second deal for the same signal, and this answers 200 with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers 201, which is how a caller tells the two apart.\",\"dateModified\":\"2026-10-27T06:52:28.510Z\",\"isPartOf\":{\"@id\":\"https://docs.openpulse.cloud#website\"},\"breadcrumb\":{\"@id\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Pipeline\",\"item\":\"https://docs.openpulse.cloud/api-reference/pipeline/list-deals\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Add a deal\",\"item\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal#apireference\",\"headline\":\"Add a deal\",\"name\":\"Add a deal\",\"description\":\"Opens one deal from the signal that prompted it. The card's signal* fields are copied from that signal here and never refreshed afterwards. Idempotent by signal. A unique index refuses a second deal for the same signal, and this answers 200 with the existing one rather than an error — adding a lead twice is a double click, not a mistake worth a red banner. A genuinely new deal answers 201, which is how a caller tells the two apart.\",\"url\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal\",\"mainEntityOfPage\":{\"@id\":\"https://docs.openpulse.cloud/api-reference/pipeline/add-a-deal#webpage\"},\"dateModified\":\"2026-10-27T06:52:28.510Z\",\"publisher\":{\"@id\":\"https://docs.openpulse.cloud/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.openpulse.cloud#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Open Pulse\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Open Pulse","nav":{"global":null,"tabs":[{"tab":"Guides","pages":[{"title":"Guides","href":""}]},{"tab":"API Reference","groups":[{"group":"Listeners","pages":[{"title":"List listeners","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/listeners","href":"/api-reference/listeners/list-listeners"},{"title":"Get one listener","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/listeners/{id}","href":"/api-reference/listeners/get-one-listener"},{"title":"Derive a listener plan from a website","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/listeners/analyse-website","href":"/api-reference/listeners/derive-a-listener-plan-from-a-website"}]},{"group":"Results","pages":[{"title":"List signals","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/results","href":"/api-reference/results/list-signals"},{"title":"Get one signal","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/results/{id}","href":"/api-reference/results/get-one-signal"},{"title":"Count signals in a window","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/results/stats","href":"/api-reference/results/count-signals-in-a-window"},{"title":"Save a signal to a list","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/signals/{id}/save","href":"/api-reference/signals/save-a-signal-to-a-list"}]},{"group":"Accounts","pages":[{"title":"List accounts","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/accounts","href":"/api-reference/accounts/list-accounts"},{"title":"Get one account","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/accounts/{key}","href":"/api-reference/accounts/get-one-account"}]},{"group":"Pipeline","pages":[{"title":"List deals","description":"Every deal in the workspace's pipeline with its stage, cursor-paginated. The board shows all columns at once by fetching pages until they are exhausted; do the same rather than assuming one response is the whole pipeline.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/pipeline","href":"/api-reference/pipeline/list-deals"},{"title":"Add a deal","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/pipeline","href":"/api-reference/pipeline/add-a-deal"},{"title":"Update a deal","description":"Moves a deal between stages, or edits its value, owner or contact. **Partial**: only the fields present are changed, and `contact` is merged field by field rather than replaced — sending `{\"contact\": {\"phone\": \"…\"}}` does not delete an email somebody else recorded.\n\nSend `null` to clear `ownerUserId` or `dealValueMinor`, and an empty string to clear a `contact` field. At least one field is required: an empty body answers 400 rather than succeeding at nothing.\n\nMoving the stage is what fires the `pipeline.stage_changed` webhook, sets `closedAt` on `won` or `lost`, and clears it again if the deal reopens.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /v1/pipeline/{id}","href":"/api-reference/pipeline/update-a-deal"},{"title":"Add several deals at once","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/pipeline/bulk","href":"/api-reference/pipeline/add-several-deals-at-once"},{"title":"Pipeline return over a window","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/pipeline/roi","href":"/api-reference/pipeline/pipeline-return-over-a-window"}]},{"group":"Collections \u0026 Notes","pages":[{"title":"Create a list","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/collections","href":"/api-reference/collections/create-a-list"},{"title":"Write a note","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /v1/notes","href":"/api-reference/notes/write-a-note"}]},{"group":"Content","pages":[{"title":"Download a push's content as a zip","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/content/pushes/{id}/export.zip","href":"/api-reference/content/download-a-pushs-content-as-a-zip"}]},{"group":"Exports","pages":[{"title":"Export accounts as CSV","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/exports/accounts.csv","href":"/api-reference/exports/export-accounts-as-csv"},{"title":"Export the pipeline as CSV","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/exports/pipeline.csv","href":"/api-reference/exports/export-the-pipeline-as-csv"},{"title":"Export signals as CSV","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /v1/exports/signals.csv","href":"/api-reference/exports/export-signals-as-csv"}]}]}]},"basePath":"","title":"Add a deal - Open Pulse","buildId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","deploymentId":"dpl_8LJbrAiZvr1K98WQNZXCyY5AvT34","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-i2a3QZ8E.js","utils-ChLwp8m0.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DRktVTDc.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-CA2pEs4T.js","snippetPresets-ClQ6XrKD.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-Ct_Lv36y.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-Cn2PYw9e.js","shallow-rkyymjXQ.js","getApiPlaygroundDisplay-BB9vkXtE.js","CodeSnippet-Bm5RU7m1.js","CodeSnippets-BgU9Deuz.js","Page-BUDYNlhG.js","getPastedJson-BD-6NNum.js","icon-8Z6tud2e.js","MethodPill-Tuzr4g3V.js","DuplicateIcon-0ceWFYhN.js","createIcon-FBXow_ST.js","DynamicMarkdown-CD8713Yy.js","SectionHeading-7zgzQbH-.js","axios-vUo_bRtp.js","Markdown-D7Ofw1oz.js","clsx-eKJ4rcii.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CwjSCXIK.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-9EK5IAXV.js"]}