{
"sampled": 186,
"available": 1240,
"verdicts": {
"allow": 151,
"warn": 19,
"block": 16,
"route": 0,
"require_approval": 0
},
"by_rule": [
{
"rule_id": "draft-0",
"rule_name": "Do not enroll contacts with an open deal",
"action": "block",
"matched": 16
},
{
"rule_id": "draft-1",
"rule_name": "Warn when another rep is already working the contact",
"action": "warn",
"matched": 19
}
],
"examples": [
{
"name": "Theresa Webb",
"verdict": "block",
"rule_name": "Do not enroll contacts with an open deal"
}
],
"unmeasured": [],
"crm_reads": []
}
{
"message": [
"rules.0.scope must contain at least 1 elements"
],
"error": "Bad Request",
"statusCode": 400,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{
"message": "The acting user is not an active member of this team",
"error": "Forbidden",
"statusCode": 403,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{
"message": "Rate limit of 300 requests per minute exceeded. Retry in 12s.",
"error": "Too Many Requests",
"statusCode": 429,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{
"message": "Internal server error",
"error": "Internal Server Error",
"statusCode": 500,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
Measures what an unsaved set of scenarios would have done to the prospects behind the team’s 200 most recent enrollments, without saving or enrolling anything.
Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose scope includes enrollment are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in unmeasured rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both.
verdicts counts allow, warn, block, route and require_approval. An example with the verdict route carries routed_to, the id of the sequence they would have started in.
Changes nothing, so it takes no Idempotency-Key. It still requires user_id, and as a POST it counts against the Sequencer writes rate limit.
POST
/
v2
/
sequencer
/
policies
/
preview
Preview a draft rule set
curl --request POST \
--url https://client-api.salesfinity.co/v2/sequencer/policies/preview \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"user_id": "64b7f0c2e4b0a1b2c3d4e5f9",
"rules": [
{
"name": "Do not enroll contacts with an open deal",
"condition_group": {
"op": "all",
"children": [
{
"type": "crm_open_deal",
"params": {}
}
]
},
"action": {
"type": "block"
},
"scope": [
"enrollment"
]
},
{
"name": "Warn when another rep is already working the contact",
"condition_group": {
"op": "all",
"children": [
{
"type": "active_in_other_sequence",
"params": {
"mode": "other_rep"
}
}
]
},
"action": {
"type": "warn"
},
"scope": [
"enrollment"
]
}
]
}
'
{
"sampled": 186,
"available": 1240,
"verdicts": {
"allow": 151,
"warn": 19,
"block": 16,
"route": 0,
"require_approval": 0
},
"by_rule": [
{
"rule_id": "draft-0",
"rule_name": "Do not enroll contacts with an open deal",
"action": "block",
"matched": 16
},
{
"rule_id": "draft-1",
"rule_name": "Warn when another rep is already working the contact",
"action": "warn",
"matched": 19
}
],
"examples": [
{
"name": "Theresa Webb",
"verdict": "block",
"rule_name": "Do not enroll contacts with an open deal"
}
],
"unmeasured": [],
"crm_reads": []
}
{
"message": [
"rules.0.scope must contain at least 1 elements"
],
"error": "Bad Request",
"statusCode": 400,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{
"message": "The acting user is not an active member of this team",
"error": "Forbidden",
"statusCode": 403,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{
"message": "Rate limit of 300 requests per minute exceeded. Retry in 12s.",
"error": "Too Many Requests",
"statusCode": 429,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{
"message": "Internal server error",
"error": "Internal Server Error",
"statusCode": 500,
"request_id": "0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"
}
{ "sampled": 186, "available": 1240, "verdicts": { "allow": 151, "warn": 19, "block": 16, "route": 0, "require_approval": 0 }, "by_rule": [ { "rule_id": "draft-0", "rule_name": "Do not enroll contacts with an open deal", "action": "block", "matched": 16 }, { "rule_id": "draft-1", "rule_name": "Warn when another rep is already working the contact", "action": "warn", "matched": 19 } ], "examples": [{ "name": "Theresa Webb", "verdict": "block", "rule_name": "Do not enroll contacts with an open deal" }], "unmeasured": [], "crm_reads": []}
Here 16 of the last 186 prospects would not have been enrolled, and 19 would have been enrolled with a warning. A rule listed in unmeasured reads a CRM field that has not been fetched for these prospects yet, so the count says nothing about it.
Only enabled rules with enrollment in scope are measured. Step rules are not.
A route_to_sequence rule counts under route, and an example with that verdict carries routed_to, the id of the sequence they would have started in.
Preview uses CRM data already stored and makes no CRM calls.
Preview checks the shape of each rule but not whether its action fits its scope. Create and update check both, so a rule that previews can still be refused on save.
The CRM fields the policy will read per prospect once live.
Show child attributes
{"docsConfig":{"theme":"aspen","$schema":"https://mintlify.com/docs.json","name":"Salesfinity Docs","description":"Learn Salesfinity, the agentic sales platform: build lists with Ari, run parallel dialing sessions, run sequences, connect your CRM, and use the REST API and MCP server. Build pipeline at superhuman speed.","colors":{"primary":"#5429D8","light":"#8B6CF0","dark":"#5429D8"},"logo":{"light":"https://mintcdn.com/salesfinity/YBsYR5N3Fg_u90-H/logo/light.svg?fit=max\u0026auto=format\u0026n=YBsYR5N3Fg_u90-H\u0026q=85\u0026s=e21e087ae3d1330def1fbf87274af05b","dark":"https://mintcdn.com/salesfinity/YBsYR5N3Fg_u90-H/logo/dark.svg?fit=max\u0026auto=format\u0026n=YBsYR5N3Fg_u90-H\u0026q=85\u0026s=3c5233eb319342816ee870dca049dbce"},"favicon":"https://mintcdn.com/salesfinity/YBsYR5N3Fg_u90-H/favicon.png?fit=max\u0026auto=format\u0026n=YBsYR5N3Fg_u90-H\u0026q=85\u0026s=6beb35ff3cf64db277c41d8e84730ceb","appearance":{"default":"light"},"background":{"color":{"light":"#F7F6FA","dark":"#0E0B18"}},"navbar":{"links":[{"href":"https://support.salesfinity.ai","label":"Help Center"},{"href":"https://web.salesfinity.co/dashboard/dialer","label":"Open Salesfinity"}],"primary":{"type":"button","label":"Book a demo","href":"https://salesfinity.ai/demo"}},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/salesfinity-co","facebook":"https://www.facebook.com/people/Salesfinity/61556891038304","website":"https://salesfinity.ai"},"links":[{"header":"Product","items":[{"label":"Salesfinity","href":"https://salesfinity.ai"},{"label":"Pricing","href":"https://salesfinity.ai/pricing"},{"label":"Integrations","href":"https://salesfinity.ai/integrations"},{"label":"Book a demo","href":"https://salesfinity.ai/demo"}]},{"header":"Resources","items":[{"label":"Help Center","href":"https://support.salesfinity.ai"},{"label":"Blog","href":"https://salesfinity.ai/blog"},{"label":"System status","href":"https://salesfinity.statuspage.io"}]},{"header":"Company","items":[{"label":"About","href":"https://salesfinity.ai/about"},{"label":"Customers","href":"https://salesfinity.ai/customers"},{"label":"Legal","href":"https://salesfinity.ai/legal"}]}]},"search":{"prompt":"Search the docs or ask a question"},"seo":{"metatags":{"og:site_name":"Salesfinity Docs","og:image":"https://docs.salesfinity.ai/images/og.jpg","og:image:width":"1200","og:image:height":"630","twitter:card":"summary_large_image","twitter:image":"https://docs.salesfinity.ai/images/og.jpg"}},"fonts":{"heading":{"family":"Onest","weight":600},"body":{"family":"Onest","weight":400}},"styling":{"eyebrows":"section","codeblocks":"system","latex":false},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"navigation":{"global":{"anchors":[{"anchor":"Help Center","icon":"circle-question","href":"https://support.salesfinity.ai"},{"anchor":"Blog","icon":"newspaper","href":"https://salesfinity.ai/blog"},{"anchor":"Status page","icon":"signal","href":"https://salesfinity.statuspage.io"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"salesfinity","hasAudioNarration":false,"actualSubdomain":"salesfinity","customDomains":["docs.salesfinity.ai"],"gitSource":{"type":"github","owner":"salesfinity-web","repo":"api-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6ad17f94e88740c316d6280b","collectionId":"68ad612b-f99a-4daf-b9c5-a935080be466","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6ad17f94e88740c316d6280b"},"entitlements":{},"buildId":"6ad17f94e88740c316d6280b","clientVersion":"0.0.3971","searchFilterCounts":[{"language":"default","tag":"Developers","count":130},{"language":"default","tag":"Sequencer API","count":77},{"language":"default","tag":"Dialer API","count":24},{"language":"default","tag":"Get started","count":22},{"language":"default","tag":"Dialer","count":20},{"language":"default","tag":"Tasks","count":17},{"language":"default","tag":"Enrollments","count":16},{"language":"default","tag":"Sequencer","count":13},{"language":"default","tag":"Use cases","count":13},{"language":"default","tag":"Help","count":12}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[],"isAtlas":false,"googleFontsInlined":true},"customCss":[{"filePath":"components.css","content":":root{--sf-accent:#5429d8;--sf-ember-deep:#0e0328;--sf-ember-violet:#5429d8;--sf-ember-magenta:#c02a8a;--sf-ember-coral:#ff5a3c;--sf-ember-head:#f5f0ff;--sf-ember-body:#d6ccf7;--sf-ember-accent:#c5b0ff;--sf-ember-shade:linear-gradient(90deg, rgba(12, 2, 44, 0.78) 0%, rgba(12, 2, 44, 0.5) 45%, rgba(12, 2, 44, 0) 75%);--sf-prompt-bg:#faf8ff;--sf-prompt-border:rgba(84, 41, 216, 0.14);--sf-prompt-text:#1d1730;--sf-prompt-muted:#6b6485;--sf-frame-bg:rgba(249, 250, 251, 0.6);--sf-frame-border:rgba(17, 12, 34, 0.08)}html.dark{--sf-prompt-bg:rgba(84, 41, 216, 0.08);--sf-prompt-border:rgba(197, 176, 255, 0.16);--sf-prompt-text:#ece7fb;--sf-prompt-muted:#a59cc4;--sf-frame-bg:rgba(31, 41, 55, 0.25);--sf-frame-border:rgba(255, 255, 255, 0.08)}.sf-prompt{position:relative;margin:1.25rem 0;border:1px solid var(--sf-prompt-border);border-left:3px solid var(--sf-accent);border-radius:12px;background:var(--sf-prompt-bg);overflow:hidden}html.dark .sf-prompt{border-left-color:var(--sf-ember-accent)}.sf-prompt-head{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem .625rem 0 1rem}.sf-prompt-copy,.sf-prompt-label{display:inline-flex;align-items:center;gap:.375rem;font-size:.75rem}.sf-prompt-label{font-weight:600;letter-spacing:.02em;text-transform:uppercase;color:var(--sf-accent)}html.dark .sf-prompt-label{color:var(--sf-ember-accent)}.sf-prompt-copy{padding:.3rem .55rem;border:1px solid transparent;border-radius:8px;background:0 0;font:inherit;font-weight:500;color:var(--sf-prompt-muted);cursor:pointer;transition:background-color 150ms ease,color 150ms ease,border-color 150ms ease}.sf-prompt-copy:hover{color:var(--sf-accent);background:rgba(84,41,216,.08);border-color:rgba(84,41,216,.14)}html.dark .sf-prompt-copy:hover{color:var(--sf-ember-head);background:rgba(197,176,255,.1);border-color:rgba(197,176,255,.18)}.sf-prompt-copy:focus-visible{outline:2px solid var(--sf-accent);outline-offset:1px}.sf-prompt-body{padding:.375rem 1rem .875rem;font-family:inherit;font-size:.9375rem;line-height:1.6;color:var(--sf-prompt-text);white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word}.sf-prompt-body p{margin:0 0 .6em}.sf-prompt-body p:last-child{margin-bottom:0}.sf-prompt-body ol,.sf-prompt-body ul{margin:.25em 0 .6em;padding-left:1.25em;white-space:normal}.sf-prompt-body ul{list-style:disc}.sf-prompt-body ol{list-style:decimal}.sf-prompt-body code{font-size:.875em;padding:.1em .3em;border-radius:4px;background:rgba(84,41,216,.08)}.sf-cover{position:relative;display:flex;align-items:flex-end;min-height:220px;margin:.5rem 0 2rem;border-radius:16px;overflow:hidden;isolation:isolate;background:radial-gradient(120% 140% at 85% 110%,var(--sf-ember-coral) 0%,rgba(255,90,60,0) 45%),radial-gradient(90% 120% at 70% 40%,var(--sf-ember-magenta) 0%,rgba(192,42,138,0) 60%),linear-gradient(120deg,var(--sf-ember-deep) 0%,var(--sf-ember-violet) 60%,var(--sf-ember-magenta) 100%);box-shadow:0 1px 2px rgba(14,3,40,.06),0 12px 32px -12px rgba(84,41,216,.35)}.sf-cover-img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;margin:0;object-fit:cover;object-position:center;border-radius:0}.sf-cover-shade{position:absolute;inset:0;z-index:-1;background:var(--sf-ember-shade)}.sf-cover-text{max-width:34rem;padding:1.75rem 2rem}.sf-cover-eyebrow{margin-bottom:.5rem;font-size:.75rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--sf-ember-accent)}.sf-cover-title{font-size:1.875rem;font-weight:650;line-height:1.15;letter-spacing:-.02em;color:var(--sf-ember-head);text-wrap:balance}.sf-cover-desc{margin-top:.625rem;font-size:1rem;line-height:1.5;color:var(--sf-ember-body);text-wrap:pretty}@media (max-width:640px){.sf-cover{min-height:168px;border-radius:12px}.sf-cover-text{padding:1.25rem}.sf-cover-title{font-size:1.5rem}.sf-cover-desc{font-size:.9375rem}.sf-cover-shade{background:linear-gradient(90deg,rgba(12,2,44,.78) 0,rgba(12,2,44,.6) 70%,rgba(12,2,44,.35) 100%)}}.sf-video{margin:1.5rem 0}.sf-video-frame{padding:.5rem;border:1px solid var(--sf-frame-border);border-radius:16px;background:var(--sf-frame-bg);overflow:hidden}.sf-video-el{display:block;width:100%;height:auto;margin:0;border-radius:10px;background:var(--sf-ember-deep);object-fit:cover}.sf-video-caption{margin-top:.625rem;padding:0 .5rem;font-size:.875rem;line-height:1.5;text-align:center;color:var(--sf-prompt-muted)}.sf-status{display:inline-flex;align-items:center;gap:.35em;padding:.15em .6em;border:1px solid transparent;border-radius:999px;font-size:.75rem;font-weight:600;line-height:1.4;letter-spacing:.01em;white-space:nowrap;vertical-align:middle}.sf-status::before{content:\"\";width:.45em;height:.45em;border-radius:999px;background:currentColor}h1 .sf-status,h2 .sf-status,h3 .sf-status,h4 .sf-status{margin-left:.5rem;font-size:.75rem;position:relative;top:-.1em}.sf-status-early-access{color:#4320b4;background:#efeaff;border-color:rgba(84,41,216,.2)}.sf-status-coming-soon{color:#8a4b05;background:#fff4dc;border-color:rgba(217,140,20,.28)}.sf-status-beta{color:#1849a9;background:#e6efff;border-color:rgba(41,112,255,.22)}html.dark .sf-status-early-access{color:#c5b0ff;background:rgba(84,41,216,.22);border-color:rgba(197,176,255,.28)}html.dark .sf-status-coming-soon{color:#fcd38d;background:rgba(217,140,20,.16);border-color:rgba(252,211,141,.26)}html.dark .sf-status-beta{color:#a4c4ff;background:rgba(41,112,255,.18);border-color:rgba(164,196,255,.26)}@media (prefers-reduced-motion:reduce){.sf-prompt-copy{transition:none}}"},{"filePath":"home.css","content":"#content-area:has(.sf-home-hero) header#header,#content-area:has(.sf-home-hero)>#header,#content-container:has(.sf-home-hero) #header{display:none}.sf-home-hero{position:relative;overflow:hidden;isolation:isolate;margin:.25rem 0 2.5rem;padding:clamp(28px,5vw,56px);min-height:320px;border-radius:20px;background:#0e0328 linear-gradient(120deg,#0e0328 0,#5429d8 45%,#c02a8a 75%,#ff5a3c 100%);box-shadow:0 18px 40px rgba(42,10,126,.16);display:flex;flex-direction:column;justify-content:center}.sf-home-hero-img{position:absolute;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;object-position:center right;margin:0!important;border-radius:0!important;max-height:none!important}.sf-home-hero-shade{position:absolute;inset:0;z-index:-1;background:linear-gradient(90deg,rgba(12,2,44,.78) 0,rgba(12,2,44,.5) 45%,rgba(12,2,44,0) 75%)}.sf-home-eyebrow{margin:0 0 14px;font-size:13px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:#c5b0ff}.sf-home-hero h1.sf-home-title{margin:0;max-width:640px;font-size:clamp(38px,5.4vw,60px);font-weight:700;line-height:1;letter-spacing:-.045em;color:#f5f0ff}.sf-home-lede{max-width:560px;margin:18px 0 0;font-size:17px;line-height:1.55;color:#d6ccf7}.sf-home-actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:28px}.sf-home-btn{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:10px 18px;border-radius:10px;font-size:15px;font-weight:600;text-decoration:none!important;border:1px solid rgba(245,240,255,.28)!important;color:#f5f0ff!important;background:rgba(245,240,255,.08);backdrop-filter:blur(8px);transition:transform .18s ease,background-color .18s ease,box-shadow .18s ease}.sf-home-btn:hover{transform:translateY(-1px);background:rgba(245,240,255,.16)}.sf-home-btn-primary{border-color:#f5f0ff!important;background:#f5f0ff;color:#2a0a7e!important}.sf-home-btn-primary:hover{background:#fff;box-shadow:0 8px 22px rgba(12,2,44,.35)}.sf-home-btn:focus-visible{outline:2px solid #c5b0ff;outline-offset:2px}.sf-home-meta{margin-top:18px;font-size:13px;color:#c5b0ff}@media (max-width:640px){.sf-home-hero{min-height:0;padding:28px 20px;border-radius:16px}.sf-home-hero-shade{background:linear-gradient(90deg,rgba(12,2,44,.8) 0,rgba(12,2,44,.62) 100%)}.sf-home-lede{font-size:16px}}@media (prefers-reduced-motion:reduce){.sf-home-btn{transition:none}.sf-home-btn:hover{transform:none}}"},{"filePath":"style.css","content":":root{--sfb-accent:#5429d8;--sfb-accent-soft:#8b6cf0;--sfb-bg:#f7f6fa;--sfb-surface:#ffffff;--sfb-muted:#f1eff6;--sfb-border:#e3dfec;--sfb-border-strong:#cdc6dc;--sfb-text:#16141c;--sfb-text-muted:#5d5a66;--sfb-accent-hover:rgba(84, 41, 216, 0.05);--sfb-accent-open:rgba(84, 41, 216, 0.03);--sfb-accent-border:rgba(84, 41, 216, 0.28);--sfb-shadow-sm:0 1px 2px rgba(42, 10, 126, 0.05);--sfb-shadow-lift:0 12px 26px -6px rgba(84, 41, 216, 0.16), 0 4px 10px -4px rgba(42, 10, 126, 0.08);--sfb-selection:rgba(84, 41, 216, 0.16)}html.dark{--sfb-accent:#8b6cf0;--sfb-accent-soft:#c5b0ff;--sfb-bg:#0e0b18;--sfb-surface:#15121f;--sfb-muted:#181524;--sfb-border:#2a2638;--sfb-border-strong:#3a3550;--sfb-text:#f5f0ff;--sfb-text-muted:#b5aed0;--sfb-accent-hover:rgba(139, 108, 240, 0.1);--sfb-accent-open:rgba(139, 108, 240, 0.07);--sfb-accent-border:rgba(139, 108, 240, 0.36);--sfb-shadow-sm:0 1px 2px rgba(0, 0, 0, 0.3);--sfb-shadow-lift:0 14px 30px -8px rgba(84, 41, 216, 0.38), 0 4px 12px -4px rgba(0, 0, 0, 0.4);--sfb-selection:rgba(139, 108, 240, 0.32)}::selection{background:var(--sfb-selection)}#content-area h1,#page-title{letter-spacing:-.03em;line-height:1.1}#content-area h2{letter-spacing:-.02em;line-height:1.2}#content-area h3,#content-area h4{letter-spacing:-.015em;line-height:1.25}.eyebrow{letter-spacing:.01em}#content-area strong{font-weight:600}#content-area img:not(.no-style):not(.sf-cover-img):not([data-component-part=card-image]){border-radius:8px}#content-area iframe{width:100%;border:0;border-radius:8px}#content-area iframe[src*=\"loom.com\"],#content-area iframe[src*=\"youtube-nocookie.com\"],#content-area iframe[src*=\"youtube.com\"]{aspect-ratio:16/9;height:auto}#content-area table,.frame{border:1px solid var(--sfb-border)}.frame{border-radius:16px!important;background:var(--sfb-muted)!important}.frame img{border-radius:10px!important}.card{border-radius:14px!important;border-color:var(--sfb-border)!important;background:var(--sfb-surface)!important;box-shadow:var(--sfb-shadow-sm);transition:transform 200ms ease,box-shadow 200ms ease,border-color 200ms ease}.card[href]:hover,a.card:hover{transform:translateY(-2px);border-color:var(--sfb-accent-border)!important;box-shadow:var(--sfb-shadow-lift)}.card img[data-component-part=card-image]{transition:transform 300ms ease}a.card:hover img[data-component-part=card-image]{transform:scale(1.03)}@media (prefers-reduced-motion:reduce){.card,.card img[data-component-part=card-image]{transition:none}.card[href]:hover,a.card:hover,a.card:hover img[data-component-part=card-image]{transform:none}}.accordion,.accordion-group{border-color:var(--sfb-border)!important}.accordion-group{background:0 0!important}.accordion{background-color:var(--sfb-muted)!important;transition:border-color 150ms ease,background-color 150ms ease}.accordion:hover{border-color:var(--sfb-accent-border)!important}.accordion[aria-expanded=true],.accordion[open]{border-color:var(--sfb-accent-border)!important;background-color:var(--sfb-accent-open)!important}details.accordion>summary{background-color:transparent!important}details.accordion>summary:hover{background-color:var(--sfb-accent-hover)!important}.accordion,.callout{border-radius:14px!important}.code-block,.code-group{border-radius:12px!important}#content-area table{border-collapse:separate;border-spacing:0;border-radius:12px;overflow:hidden;font-size:.9375rem}#content-area tbody td,#content-area thead th{border-bottom:1px solid var(--sfb-border)!important}#content-area thead th{background:var(--sfb-muted);color:var(--sfb-text);font-weight:600;font-size:.8125rem;letter-spacing:.01em}#content-area td,#content-area th{padding:.65rem .9rem!important;vertical-align:top}#content-area tbody td{border-top:0!important}#content-area tbody tr:last-child td{border-bottom:0!important}#content-area tbody tr:hover td{background:var(--sfb-accent-hover)}#topbar-cta-button a>span:first-child{border-radius:9999px;transition:box-shadow 150ms ease}#topbar-cta-button a{padding-left:.9rem;padding-right:.7rem;transition:transform 150ms ease}#topbar-cta-button a:hover{transform:translateY(-1px)}#topbar-cta-button a:hover>span:first-child{box-shadow:0 6px 16px rgba(84,41,216,.32)}a[href*=\"utm_campaign=poweredBy\"]{display:none!important}*{scrollbar-width:thin;scrollbar-color:var(--sfb-border-strong) transparent}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-thumb{background:var(--sfb-border-strong);border-radius:9999px}::-webkit-scrollbar-track{background:0 0}"}],"page":{"pagePath":"api-reference/endpoint/preview-sequencer-policy","slug":"/api-reference/endpoint/preview-sequencer-policy","pageMetadata":{"title":"Preview a draft rule set","openapi":"POST /v2/sequencer/policies/preview","description":"Measures what an unsaved set of scenarios would have done to the prospects behind the team's 200 most recent enrollments, without saving or enrolling anything.\n\nRun it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose `scope` includes `enrollment` are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in `unmeasured` rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both.\n\n`verdicts` counts `allow`, `warn`, `block`, `route` and `require_approval`. An example with the verdict `route` carries `routed_to`, the id of the sequence they would have started in.\n\nChanges nothing, so it takes no `Idempotency-Key`. It still requires `user_id`, and as a `POST` it counts against the Sequencer writes [rate limit](/api-reference/rate-limits).","href":"/api-reference/endpoint/preview-sequencer-policy"},"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 a: \"a\",\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Measures what an unsaved set of scenarios would have done to the prospects behind the team’s 200 most recent enrollments, without saving or enrolling anything.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose \", _jsx(_components.code, {\n children: \"scope\"\n }), \" includes \", _jsx(_components.code, {\n children: \"enrollment\"\n }), \" are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in \", _jsx(_components.code, {\n children: \"unmeasured\"\n }), \" rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"verdicts\"\n }), \" counts \", _jsx(_components.code, {\n children: \"allow\"\n }), \", \", _jsx(_components.code, {\n children: \"warn\"\n }), \", \", _jsx(_components.code, {\n children: \"block\"\n }), \", \", _jsx(_components.code, {\n children: \"route\"\n }), \" and \", _jsx(_components.code, {\n children: \"require_approval\"\n }), \". An example with the verdict \", _jsx(_components.code, {\n children: \"route\"\n }), \" carries \", _jsx(_components.code, {\n children: \"routed_to\"\n }), \", the id of the sequence they would have started in.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Changes nothing, so it takes no \", _jsx(_components.code, {\n children: \"Idempotency-Key\"\n }), \". It still requires \", _jsx(_components.code, {\n children: \"user_id\"\n }), \", and as a \", _jsx(_components.code, {\n children: \"POST\"\n }), \" it counts against the Sequencer writes \", _jsx(_components.a, {\n href: \"/api-reference/rate-limits\",\n children: \"rate limit\"\n }), \".\"]\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,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,li:`li`,p:`p`,pre:`pre`,span:`span`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);return _jsxs(_Fragment,{children:[_jsx(_components.p,{children:`Shows what a set of scenarios would have done to the team’s recent prospects, before you save it. Nothing is saved and nobody is enrolled.`}),`\n`,_jsx(Heading,{level:`2`,id:`reading-the-result`,children:`Reading the result`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`12`,language:`json`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`json`,children:_jsxs(_components.code,{language:`json`,numberOfLines:`12`,children:[_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`{`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"sampled\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`186`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"available\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1240`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`,`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"verdicts\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"allow\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`151`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"warn\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`19`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"block\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`16`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"route\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"require_approval\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`0`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"by_rule\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"rule_id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"draft-0\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"rule_name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Do not enroll contacts with an open deal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"action\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"block\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"matched\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`16`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` },`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"rule_id\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"draft-1\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"rule_name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Warn when another rep is already working the contact\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"action\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"warn\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"matched\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`19`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` ],`})}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"examples\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [{ `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Theresa Webb\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"verdict\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"block\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:`\"rule_name\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"Do not enroll contacts with an open deal\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` }],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"unmeasured\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [],`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#9CDCFE`},children:` \"crm_reads\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: []`})]}),`\n`,_jsx(_components.span,{className:`line`,children:_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`}`})}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Here 16 of the last 186 prospects would not have been enrolled, and 19 would have been enrolled with a warning. A rule listed in `,_jsx(_components.code,{children:`unmeasured`}),` reads a CRM field that has not been fetched for these prospects yet, so the count says nothing about it.`]}),`\n`,_jsx(Heading,{level:`2`,id:`good-to-know`,children:`Good to know`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[`Only enabled rules with `,_jsx(_components.code,{children:`enrollment`}),` in `,_jsx(_components.code,{children:`scope`}),` are measured. Step rules are not.`]}),`\n`,_jsxs(_components.li,{children:[`A `,_jsx(_components.code,{children:`route_to_sequence`}),` rule counts under `,_jsx(_components.code,{children:`route`}),`, and an example with that verdict carries `,_jsx(_components.code,{children:`routed_to`}),`, the id of the sequence they would have started in.`]}),`\n`,_jsx(_components.li,{children:`Preview uses CRM data already stored and makes no CRM calls.`}),`\n`,_jsx(_components.li,{children:`Preview checks the shape of each rule but not whether its action fits its scope. Create and update check both, so a rule that previews can still be refused on save.`}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"codeStyling":"system","config":{},"pageMetadata":{"title":"Preview a draft rule set","openapi":"POST /v2/sequencer/policies/preview","description":"Measures what an unsaved set of scenarios would have done to the prospects behind the team's 200 most recent enrollments, without saving or enrolling anything.\n\nRun it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose `scope` includes `enrollment` are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in `unmeasured` rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both.\n\n`verdicts` counts `allow`, `warn`, `block`, `route` and `require_approval`. An example with the verdict `route` carries `routed_to`, the id of the sequence they would have started in.\n\nChanges nothing, so it takes no `Idempotency-Key`. It still requires `user_id`, and as a `POST` it counts against the Sequencer writes [rate limit](/api-reference/rate-limits).","href":"/api-reference/endpoint/preview-sequencer-policy"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Reading the result","slug":"reading-the-result","depth":2,"children":[]},{"title":"Good to know","slug":"good-to-know","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"operationId":"preview-sequencer-policy","summary":"Preview a draft rule set","description":"Measures what an unsaved set of scenarios would have done to the prospects behind the team's 200 most recent enrollments, without saving or enrolling anything.\n\nRun it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose `scope` includes `enrollment` are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in `unmeasured` rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both.\n\n`verdicts` counts `allow`, `warn`, `block`, `route` and `require_approval`. An example with the verdict `route` carries `routed_to`, the id of the sequence they would have started in.\n\nChanges nothing, so it takes no `Idempotency-Key`. It still requires `user_id`, and as a `POST` it counts against the Sequencer writes [rate limit](/api-reference/rate-limits).","parameters":[],"requestBody":"78d0f7d6-95d5-48e9-a6ea-ef9871bab772","responses":{"200":"95a78484-2372-42bf-84cb-6047109417be","400":"72a73454-16c1-4e58-913d-c0cb52358b83","403":"b4ed1aed-db9e-46ec-b93e-a2edb0f6a662","429":"5d92512f-5488-4840-9340-bdb64342816d","500":"e5374163-40c5-4d47-948d-2e06cd7e7f8a","502":"68569edb-b263-4549-a52e-2c40dce35841","504":"14d3f98d-739c-4362-8988-2119c6796470"},"tags":["Sequencer Policies"],"method":"post","type":"path","servers":["e454be74-cffb-47a4-ba19-76c8aa914a2a"],"security":["d89798b7-2249-48bf-bec9-f116988c3362"],"path":"/v2/sequencer/policies/preview","baseUrlOptions":["https://client-api.salesfinity.co"],"title":"Preview a draft rule set","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","description":"The team member this call acts as. Must be an active member of the team the API key belongs to.","example":"507f1f77bcf86cd799439011","isRequired":true,"uniqueKey":"user_id","typeLabel":"string"},"rules":{"description":"The draft scenarios to measure, up to 100. Not saved. Only enabled rules with `enrollment` in `scope` are measured.","type":"array","maxItems":100,"items":{"type":"object","description":"A scenario: a condition or condition group, an action, and where it is checked.","properties":{"name":{"type":"string","maxLength":200,"description":"Shown to reps as the reason when the rule fires, so write it as one. Must not be empty.","isRequired":true,"uniqueKey":"rules.items.[INDEX].name","typeLabel":"string"},"action":{"type":"object","properties":{"type":{"type":"string","maxLength":100,"description":"An action type from the catalog. In a scenario's `action`, one of `actions`: `block`, `warn`, `require_approval` or `route_to_sequence` (at `enrollment` only; `route_to_sequence` starts them in another sequence instead of this one), or `skip_step`, `pause` or `finish` (before a step only). In a reaction's `actions`, one of `outcome_actions`: `finish_contact`, `pause_contact`, `enroll_in_sequence`, `create_task`, `finish_account_mates` or `pause_account_mates`.","isRequired":true,"uniqueKey":"rules.items.[INDEX].action.type","typeLabel":"string"},"params":{"type":"object","description":"Parameters as the catalog describes them, for example `{ \"sequence\": \"\u003csequence id>\" }` for `route_to_sequence` (required: one of your team's sequences that is not archived), `{ \"days\": 7 }` for `pause` or `{ \"scope\": \"team\" }` for `finish_account_mates`. Unknown keys are refused.","uniqueKey":"rules.items.[INDEX].action.params","typeLabel":"object"}},"required":["type"],"isRequired":true,"uniqueKey":"rules.items.[INDEX].action","typeLabel":"object"},"scope":{"description":"Where the rule is checked: 1 to 4 of `enrollment`, `step` (before every step), `email_step` and `call_step`. Every condition and the action must be valid at each scope listed.","type":"array","maxItems":4,"items":{"type":"string","uniqueKey":"rules.items.[INDEX].scope.items.[INDEX]","typeLabel":"string"},"isRequired":true,"uniqueKey":"rules.items.[INDEX].scope","typeLabel":"string[]"},"id":{"type":"string","maxLength":64,"description":"Stable id. Generated when omitted. Keep it when you resend a rule on update, so timeline rows that cite the rule stay linked.","uniqueKey":"rules.items.[INDEX].id","typeLabel":"string"},"enabled":{"type":"boolean","default":true,"description":"A disabled rule is kept but not evaluated.","uniqueKey":"rules.items.[INDEX].enabled","typeLabel":"boolean"},"condition":{"type":"object","description":"A single condition. Send either `condition` or `condition_group`.","required":["type"],"properties":{"type":{"type":"string","maxLength":100,"description":"A condition type from the catalog's `conditions`: `crm_owner_is_other_rep`, `crm_open_deal`, `crm_record_field`, `crm_opted_out`, `active_in_other_sequence`, `touched_within_days`, `emails_unopened_streak`, `calls_unanswered_streak`, `contact_field`, `prior_calls`, `last_call_result` or `had_call_result` (`crm_field` is deprecated). The last three read the person's call history from any list in the dialer or any sequence, by anyone on the team, and are valid at every scope. The catalog is the live list and says which scopes each type allows.","isRequired":true,"uniqueKey":"rules.items.[INDEX].condition.type","typeLabel":"string"},"params":{"type":"object","description":"Parameters as the catalog describes them, for example `{ \"count\": 3 }` for `emails_unopened_streak`. Unknown keys are refused. For the call-history conditions:\n\n- `prior_calls`: `count` (1 to 100, required), `within_days` (1 to 365, default 90) and `only_unanswered` (default `false`). Matches when they were called at least `count` times in the window.\n- `last_call_result`: `dispositions` (result ids, the `id` from `GET /v1/dispositions`; required) and `within_days` (1 to 365; leave it out for any time). Matches when their most recent call's result is one of them.\n- `had_call_result`: `dispositions` (required), `window` (`within_days`, the default, `more_than_days_ago` or `any_time`) and `days` (1 to 1,095, default 180). Matches when any of their latest 100 calls got one of them; `more_than_days_ago` goes by the most recent such call. Salesfinity fills in `result_labels` on save.","uniqueKey":"rules.items.[INDEX].condition.params","typeLabel":"object"}},"uniqueKey":"rules.items.[INDEX].condition","typeLabel":"object"},"condition_group":{"type":"object","description":"An `all` (AND) or `any` (OR) group, for rules with more than one condition: `{ \"op\": \"all\", \"children\": [ ... ] }`. Each child is a condition (`type`, `params`, and `negate: true` to invert it) or another group. At most 3 levels deep and 30 conditions in all.","uniqueKey":"rules.items.[INDEX].condition_group","typeLabel":"object"},"sequences":{"description":"The sequences this rule applies to, up to 50 ids. Leave it out, or send `[]`, for every sequence that uses the policy. Rules are replaced whole on update, so keep this list when you send back a rule you read, or the rule starts applying to every sequence.","type":"array","maxItems":50,"items":{"type":"string","uniqueKey":"rules.items.[INDEX].sequences.items.[INDEX]","typeLabel":"string"},"uniqueKey":"rules.items.[INDEX].sequences","typeLabel":"string[]"}},"required":["name","action","scope"],"example":{"name":"Do not enroll contacts with an open deal","condition_group":{"op":"all","children":[{"type":"crm_open_deal","params":{}}]},"action":{"type":"block"},"scope":["enrollment"]},"uniqueKey":"rules.items.[INDEX]","typeLabel":"object"},"uniqueKey":"rules","typeLabel":"object[]"}},"required":["user_id"],"example":{"user_id":"64b7f0c2e4b0a1b2c3d4e5f9","rules":[{"name":"Do not enroll contacts with an open deal","condition_group":{"op":"all","children":[{"type":"crm_open_deal","params":{}}]},"action":{"type":"block"},"scope":["enrollment"]},{"name":"Warn when another rep is already working the contact","condition_group":{"op":"all","children":[{"type":"active_in_other_sequence","params":{"mode":"other_rep"}}]},"action":{"type":"warn"},"scope":["enrollment"]}]},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"user_id":"64b7f0c2e4b0a1b2c3d4e5f9","rules":[{"name":"Do not enroll contacts with an open deal","condition_group":{"op":"all","children":[{"type":"crm_open_deal","params":{}}]},"action":{"type":"block"},"scope":["enrollment"]},{"name":"Warn when another rep is already working the contact","condition_group":{"op":"all","children":[{"type":"active_in_other_sequence","params":{"mode":"other_rep"}}]},"action":{"type":"warn"},"scope":["enrollment"]}]}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"95a78484-2372-42bf-84cb-6047109417be":{"description":"What the draft would have done.","headers":{"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"X-RateLimit-Limit":{"description":"Requests allowed per minute in the rate-limit bucket this request counted against. Limits are per team: every API key on the team shares them.","schema":{"type":"integer"},"example":300},"X-RateLimit-Remaining":{"description":"Requests left in the current one-minute window for this bucket.","schema":{"type":"integer","minimum":0},"example":0},"X-RateLimit-Reset":{"description":"Seconds until the current window ends and the bucket resets. At least 1 and at most 60.","schema":{"type":"integer","minimum":0},"example":12}},"content":{"application/json":{"schema":{"type":"object","properties":{"sampled":{"type":"integer","description":"Prospects evaluated: the distinct contacts behind the 200 most recent enrollments.","isRequired":true,"uniqueKey":"sampled","typeLabel":"integer"},"available":{"type":"integer","description":"Enrollments the team has ever had, so a thin sample is visibly thin.","isRequired":true,"uniqueKey":"available","typeLabel":"integer"},"verdicts":{"type":"object","description":"How many sampled prospects each verdict would have applied to.","properties":{"allow":{"type":"integer","uniqueKey":"verdicts.allow","typeLabel":"integer"},"warn":{"type":"integer","uniqueKey":"verdicts.warn","typeLabel":"integer"},"block":{"type":"integer","uniqueKey":"verdicts.block","typeLabel":"integer"},"route":{"type":"integer","description":"Would have been started in another sequence by a `route_to_sequence` rule.","uniqueKey":"verdicts.route","typeLabel":"integer"},"require_approval":{"type":"integer","uniqueKey":"verdicts.require_approval","typeLabel":"integer"}},"isRequired":true,"uniqueKey":"verdicts","typeLabel":"object"},"by_rule":{"type":"array","description":"Per measured rule, in policy order. A prospect can match several rules.","items":{"type":"object","properties":{"rule_id":{"type":"string","description":"The rule's `id`, or `draft-\u003cindex>` when it had none.","uniqueKey":"by_rule.items.[INDEX].rule_id","typeLabel":"string"},"rule_name":{"type":"string","uniqueKey":"by_rule.items.[INDEX].rule_name","typeLabel":"string"},"action":{"type":"string","uniqueKey":"by_rule.items.[INDEX].action","typeLabel":"string"},"matched":{"type":"integer","uniqueKey":"by_rule.items.[INDEX].matched","typeLabel":"integer"}},"uniqueKey":"by_rule.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"by_rule","typeLabel":"object[]"},"examples":{"type":"array","description":"Up to 5 prospects who would not simply have been allowed.","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"examples.items.[INDEX].name","typeLabel":"string"},"verdict":{"type":"string","uniqueKey":"examples.items.[INDEX].verdict","typeLabel":"string"},"rule_name":{"type":"string","uniqueKey":"examples.items.[INDEX].rule_name","typeLabel":"string"},"reason":{"type":"string","uniqueKey":"examples.items.[INDEX].reason","typeLabel":"string"},"routed_to":{"type":"string","description":"When `verdict` is `route`: the id of the sequence they would have started in.","uniqueKey":"examples.items.[INDEX].routed_to","typeLabel":"string"}},"uniqueKey":"examples.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"examples","typeLabel":"object[]"},"unmeasured":{"type":"array","description":"Rules that could not be measured, with why.","items":{"type":"object","properties":{"rule_id":{"type":"string","uniqueKey":"unmeasured.items.[INDEX].rule_id","typeLabel":"string"},"rule_name":{"type":"string","uniqueKey":"unmeasured.items.[INDEX].rule_name","typeLabel":"string"},"reason":{"type":"string","uniqueKey":"unmeasured.items.[INDEX].reason","typeLabel":"string"}},"uniqueKey":"unmeasured.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"unmeasured","typeLabel":"object[]"},"crm_reads":{"type":"array","description":"The CRM fields the policy will read per prospect once live.","items":{"type":"object","properties":{"source":{"type":"string","uniqueKey":"crm_reads.items.[INDEX].source","typeLabel":"string"},"object":{"type":"string","uniqueKey":"crm_reads.items.[INDEX].object","typeLabel":"string"},"fields":{"type":"array","items":{"type":"string","uniqueKey":"crm_reads.items.[INDEX].fields.items.[INDEX]","typeLabel":"string"},"uniqueKey":"crm_reads.items.[INDEX].fields","typeLabel":"string[]"}},"uniqueKey":"crm_reads.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"crm_reads","typeLabel":"object[]"}},"required":["sampled","available","verdicts","by_rule","examples","unmeasured","crm_reads"],"uniqueKey":"","typeLabel":"object"},"example":{"sampled":186,"available":1240,"verdicts":{"allow":151,"warn":19,"block":16,"route":0,"require_approval":0},"by_rule":[{"rule_id":"draft-0","rule_name":"Do not enroll contacts with an open deal","action":"block","matched":16},{"rule_id":"draft-1","rule_name":"Warn when another rep is already working the contact","action":"warn","matched":19}],"examples":[{"name":"Theresa Webb","verdict":"block","rule_name":"Do not enroll contacts with an open deal"}],"unmeasured":[],"crm_reads":[]},"examples":{"Example":{"title":"Example","value":{"sampled":186,"available":1240,"verdicts":{"allow":151,"warn":19,"block":16,"route":0,"require_approval":0},"by_rule":[{"rule_id":"draft-0","rule_name":"Do not enroll contacts with an open deal","action":"block","matched":16},{"rule_id":"draft-1","rule_name":"Warn when another rep is already working the contact","action":"warn","matched":19}],"examples":[{"name":"Theresa Webb","verdict":"block","rule_name":"Do not enroll contacts with an open deal"}],"unmeasured":[],"crm_reads":[]}}},"exampleType":"examples"}},"exampleType":"examples"},"72a73454-16c1-4e58-913d-c0cb52358b83":{"description":"Validation failed. Check the request body and query parameters against the schema on this operation. `message` lists every field that failed validation.","headers":{"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}},"content":{"application/json":{"schema":{"type":"object","title":"Error","description":"The error envelope returned by every Salesfinity API error response. The shape is identical across all status codes and all endpoints, and `request_id` is present on every error the API returns.","required":["message","error","statusCode","request_id"],"properties":{"message":{"oneOf":[{"type":"string","description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Stable HTTP reason phrase for the status code, such as `Forbidden`. One exception: a 403 from a `/v2/sequencer` write whose `user_id` has no active plan or seat carries `NO_ACTIVE_PLAN` here. Branch on this rather than on `message`.","example":"Forbidden","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","format":"int32","description":"HTTP status code, repeated in the body so it survives transports that drop it.","example":403,"isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer\u003cint32>"},"request_id":{"type":"string","description":"Identifies the request in Salesfinity's logs; the same value as the `X-Request-Id` response header. Include it when you contact support.","example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"errors":{"type":"array","items":{"type":"string","uniqueKey":"errors.items.[INDEX]","typeLabel":"string"},"description":"Present on a few Sequencer errors, such as a rules-of-engagement policy whose rules fail the catalog check: one entry per problem. Other fields an upstream service sends are passed through unchanged too.","uniqueKey":"errors","typeLabel":"string[]"},"code":{"type":"string","description":"A machine-readable reason, present on a few Sequencer errors. `unknown_variables`: a template, a step's name or a step's note holds a token that is not a variable; `unknown` lists each one.","uniqueKey":"code","typeLabel":"string"},"unknown":{"type":"array","description":"Present when `code` is `unknown_variables`: one entry per distinct token that was refused.","items":{"type":"object","description":"A token in double braces that is not a variable, or cannot be used where it was written.","properties":{"token":{"type":"string","description":"The token as written, braces included, such as `{{fisrt_name}}`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].token","typeLabel":"string"},"key":{"type":"string","description":"What is inside the braces, lower-cased, without the fallback.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].key","typeLabel":"string"},"reason":{"type":"string","enum":["not_a_variable","empty","fallback_too_long","unbalanced","not_allowed_here"],"description":"`not_a_variable`: not a built-in variable, not a custom field your team has, and not an AI line (a misspelt AI line such as `{{ ai:opener }}` lands here too). `empty`: nothing to read, as in `{{}}`, `{{ |x}}` or `{{custom.}}`. `fallback_too_long`: the fallback is over 64 characters. `unbalanced`: braces that do not pair up, as in `{{first_name` or `{{first_name}}}`. `not_allowed_here`: a step's name or note only, for an AI line, or for any variable in an email step's name.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"suggestion":{"oneOf":[{"type":"object","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.key","typeLabel":"string"},"label":{"type":"string","description":"Its name in the app, such as `First name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.label","typeLabel":"string"}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0","typeLabel":"object"},{"type":"null","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`."},"label":{"type":"string","description":"Its name in the app, such as `First name`."}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion","typeLabel":"object | null"},"message":{"type":"string","description":"A sentence to show a person, such as `fisrt_name isn't a variable. Did you mean First name?`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].message","typeLabel":"string"},"field":{"type":"string","enum":["display_name","task_note"],"description":"Step writes only: the field the token is in.","uniqueKey":"unknown.items.[INDEX].field","typeLabel":"enum\u003cstring>"}},"required":["token","key","reason","suggestion","message"],"uniqueKey":"unknown.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unknown","typeLabel":"object[]"}},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"uniqueKey":"","typeLabel":"Error · object"},"example":{"message":["rules.0.scope must contain at least 1 elements"],"error":"Bad Request","statusCode":400,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"examples":{"Example":{"title":"Example","value":{"message":["rules.0.scope must contain at least 1 elements"],"error":"Bad Request","statusCode":400,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}}},"exampleType":"examples"}},"exampleType":"examples"},"b4ed1aed-db9e-46ec-b93e-a2edb0f6a662":{"description":"Forbidden. Either the `x-api-key` header is missing, malformed, revoked or belongs to another team, or `user_id` is not an active member of the key's team (`The acting user is not an active member of this team`).","headers":{"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}},"content":{"application/json":{"schema":{"type":"object","title":"Error","description":"The error envelope returned by every Salesfinity API error response. The shape is identical across all status codes and all endpoints, and `request_id` is present on every error the API returns.","required":["message","error","statusCode","request_id"],"properties":{"message":{"oneOf":[{"type":"string","description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Stable HTTP reason phrase for the status code, such as `Forbidden`. One exception: a 403 from a `/v2/sequencer` write whose `user_id` has no active plan or seat carries `NO_ACTIVE_PLAN` here. Branch on this rather than on `message`.","example":"Forbidden","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","format":"int32","description":"HTTP status code, repeated in the body so it survives transports that drop it.","example":403,"isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer\u003cint32>"},"request_id":{"type":"string","description":"Identifies the request in Salesfinity's logs; the same value as the `X-Request-Id` response header. Include it when you contact support.","example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"errors":{"type":"array","items":{"type":"string","uniqueKey":"errors.items.[INDEX]","typeLabel":"string"},"description":"Present on a few Sequencer errors, such as a rules-of-engagement policy whose rules fail the catalog check: one entry per problem. Other fields an upstream service sends are passed through unchanged too.","uniqueKey":"errors","typeLabel":"string[]"},"code":{"type":"string","description":"A machine-readable reason, present on a few Sequencer errors. `unknown_variables`: a template, a step's name or a step's note holds a token that is not a variable; `unknown` lists each one.","uniqueKey":"code","typeLabel":"string"},"unknown":{"type":"array","description":"Present when `code` is `unknown_variables`: one entry per distinct token that was refused.","items":{"type":"object","description":"A token in double braces that is not a variable, or cannot be used where it was written.","properties":{"token":{"type":"string","description":"The token as written, braces included, such as `{{fisrt_name}}`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].token","typeLabel":"string"},"key":{"type":"string","description":"What is inside the braces, lower-cased, without the fallback.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].key","typeLabel":"string"},"reason":{"type":"string","enum":["not_a_variable","empty","fallback_too_long","unbalanced","not_allowed_here"],"description":"`not_a_variable`: not a built-in variable, not a custom field your team has, and not an AI line (a misspelt AI line such as `{{ ai:opener }}` lands here too). `empty`: nothing to read, as in `{{}}`, `{{ |x}}` or `{{custom.}}`. `fallback_too_long`: the fallback is over 64 characters. `unbalanced`: braces that do not pair up, as in `{{first_name` or `{{first_name}}}`. `not_allowed_here`: a step's name or note only, for an AI line, or for any variable in an email step's name.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"suggestion":{"oneOf":[{"type":"object","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.key","typeLabel":"string"},"label":{"type":"string","description":"Its name in the app, such as `First name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.label","typeLabel":"string"}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0","typeLabel":"object"},{"type":"null","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`."},"label":{"type":"string","description":"Its name in the app, such as `First name`."}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion","typeLabel":"object | null"},"message":{"type":"string","description":"A sentence to show a person, such as `fisrt_name isn't a variable. Did you mean First name?`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].message","typeLabel":"string"},"field":{"type":"string","enum":["display_name","task_note"],"description":"Step writes only: the field the token is in.","uniqueKey":"unknown.items.[INDEX].field","typeLabel":"enum\u003cstring>"}},"required":["token","key","reason","suggestion","message"],"uniqueKey":"unknown.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unknown","typeLabel":"object[]"}},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"uniqueKey":"","typeLabel":"Error · object"},"example":{"message":"The acting user is not an active member of this team","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"examples":{"Example":{"title":"Example","value":{"message":"The acting user is not an active member of this team","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}}},"exampleType":"examples"}},"exampleType":"examples"},"5d92512f-5488-4840-9340-bdb64342816d":{"description":"Too Many Requests. The team has used its per-minute budget for this rate-limit bucket; the limit is shared by every API key on the team. Wait the number of seconds in the `Retry-After` header (never more than 60), then retry. The request was refused before it ran, so retrying it is safe even for a write. Pace bulk work with the `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers. See /api-reference/rate-limits.","headers":{"Retry-After":{"description":"Seconds to wait before retrying: the time left in the current one-minute window. At least 1 and at most 60.","schema":{"type":"integer","minimum":0},"example":12},"X-RateLimit-Limit":{"description":"Requests allowed per minute in the rate-limit bucket this request counted against. Limits are per team: every API key on the team shares them.","schema":{"type":"integer"},"example":300},"X-RateLimit-Remaining":{"description":"Requests left in the current one-minute window for this bucket.","schema":{"type":"integer","minimum":0},"example":0},"X-RateLimit-Reset":{"description":"Seconds until the current window ends and the bucket resets. At least 1 and at most 60.","schema":{"type":"integer","minimum":0},"example":12},"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}},"content":{"application/json":{"schema":{"type":"object","title":"Error","description":"The error envelope returned by every Salesfinity API error response. The shape is identical across all status codes and all endpoints, and `request_id` is present on every error the API returns.","required":["message","error","statusCode","request_id"],"properties":{"message":{"oneOf":[{"type":"string","description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Stable HTTP reason phrase for the status code, such as `Forbidden`. One exception: a 403 from a `/v2/sequencer` write whose `user_id` has no active plan or seat carries `NO_ACTIVE_PLAN` here. Branch on this rather than on `message`.","example":"Forbidden","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","format":"int32","description":"HTTP status code, repeated in the body so it survives transports that drop it.","example":403,"isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer\u003cint32>"},"request_id":{"type":"string","description":"Identifies the request in Salesfinity's logs; the same value as the `X-Request-Id` response header. Include it when you contact support.","example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"errors":{"type":"array","items":{"type":"string","uniqueKey":"errors.items.[INDEX]","typeLabel":"string"},"description":"Present on a few Sequencer errors, such as a rules-of-engagement policy whose rules fail the catalog check: one entry per problem. Other fields an upstream service sends are passed through unchanged too.","uniqueKey":"errors","typeLabel":"string[]"},"code":{"type":"string","description":"A machine-readable reason, present on a few Sequencer errors. `unknown_variables`: a template, a step's name or a step's note holds a token that is not a variable; `unknown` lists each one.","uniqueKey":"code","typeLabel":"string"},"unknown":{"type":"array","description":"Present when `code` is `unknown_variables`: one entry per distinct token that was refused.","items":{"type":"object","description":"A token in double braces that is not a variable, or cannot be used where it was written.","properties":{"token":{"type":"string","description":"The token as written, braces included, such as `{{fisrt_name}}`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].token","typeLabel":"string"},"key":{"type":"string","description":"What is inside the braces, lower-cased, without the fallback.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].key","typeLabel":"string"},"reason":{"type":"string","enum":["not_a_variable","empty","fallback_too_long","unbalanced","not_allowed_here"],"description":"`not_a_variable`: not a built-in variable, not a custom field your team has, and not an AI line (a misspelt AI line such as `{{ ai:opener }}` lands here too). `empty`: nothing to read, as in `{{}}`, `{{ |x}}` or `{{custom.}}`. `fallback_too_long`: the fallback is over 64 characters. `unbalanced`: braces that do not pair up, as in `{{first_name` or `{{first_name}}}`. `not_allowed_here`: a step's name or note only, for an AI line, or for any variable in an email step's name.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"suggestion":{"oneOf":[{"type":"object","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.key","typeLabel":"string"},"label":{"type":"string","description":"Its name in the app, such as `First name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.label","typeLabel":"string"}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0","typeLabel":"object"},{"type":"null","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`."},"label":{"type":"string","description":"Its name in the app, such as `First name`."}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion","typeLabel":"object | null"},"message":{"type":"string","description":"A sentence to show a person, such as `fisrt_name isn't a variable. Did you mean First name?`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].message","typeLabel":"string"},"field":{"type":"string","enum":["display_name","task_note"],"description":"Step writes only: the field the token is in.","uniqueKey":"unknown.items.[INDEX].field","typeLabel":"enum\u003cstring>"}},"required":["token","key","reason","suggestion","message"],"uniqueKey":"unknown.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unknown","typeLabel":"object[]"}},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"uniqueKey":"","typeLabel":"Error · object"},"example":{"message":"Rate limit of 300 requests per minute exceeded. Retry in 12s.","error":"Too Many Requests","statusCode":429,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"examples":{"Example":{"title":"Example","value":{"message":"Rate limit of 300 requests per minute exceeded. Retry in 12s.","error":"Too Many Requests","statusCode":429,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}}},"exampleType":"examples"}},"exampleType":"examples"},"e5374163-40c5-4d47-948d-2e06cd7e7f8a":{"description":"Internal Server Error. Something went wrong on the Salesfinity side. Retry with exponential backoff. If it persists, contact [email protected] with the `request_id` from the body, the request path and the timestamp. The contact-list, snoozed-contact and note routes do not validate an ID in the path, and the analytics routes do not validate `user_ids`: an ID that is not a 24-character hexadecimal string returns 500 there, and retrying does not help, so check the ID first.","headers":{"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}},"content":{"application/json":{"schema":{"type":"object","title":"Error","description":"The error envelope returned by every Salesfinity API error response. The shape is identical across all status codes and all endpoints, and `request_id` is present on every error the API returns.","required":["message","error","statusCode","request_id"],"properties":{"message":{"oneOf":[{"type":"string","description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Stable HTTP reason phrase for the status code, such as `Forbidden`. One exception: a 403 from a `/v2/sequencer` write whose `user_id` has no active plan or seat carries `NO_ACTIVE_PLAN` here. Branch on this rather than on `message`.","example":"Forbidden","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","format":"int32","description":"HTTP status code, repeated in the body so it survives transports that drop it.","example":403,"isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer\u003cint32>"},"request_id":{"type":"string","description":"Identifies the request in Salesfinity's logs; the same value as the `X-Request-Id` response header. Include it when you contact support.","example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"errors":{"type":"array","items":{"type":"string","uniqueKey":"errors.items.[INDEX]","typeLabel":"string"},"description":"Present on a few Sequencer errors, such as a rules-of-engagement policy whose rules fail the catalog check: one entry per problem. Other fields an upstream service sends are passed through unchanged too.","uniqueKey":"errors","typeLabel":"string[]"},"code":{"type":"string","description":"A machine-readable reason, present on a few Sequencer errors. `unknown_variables`: a template, a step's name or a step's note holds a token that is not a variable; `unknown` lists each one.","uniqueKey":"code","typeLabel":"string"},"unknown":{"type":"array","description":"Present when `code` is `unknown_variables`: one entry per distinct token that was refused.","items":{"type":"object","description":"A token in double braces that is not a variable, or cannot be used where it was written.","properties":{"token":{"type":"string","description":"The token as written, braces included, such as `{{fisrt_name}}`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].token","typeLabel":"string"},"key":{"type":"string","description":"What is inside the braces, lower-cased, without the fallback.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].key","typeLabel":"string"},"reason":{"type":"string","enum":["not_a_variable","empty","fallback_too_long","unbalanced","not_allowed_here"],"description":"`not_a_variable`: not a built-in variable, not a custom field your team has, and not an AI line (a misspelt AI line such as `{{ ai:opener }}` lands here too). `empty`: nothing to read, as in `{{}}`, `{{ |x}}` or `{{custom.}}`. `fallback_too_long`: the fallback is over 64 characters. `unbalanced`: braces that do not pair up, as in `{{first_name` or `{{first_name}}}`. `not_allowed_here`: a step's name or note only, for an AI line, or for any variable in an email step's name.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"suggestion":{"oneOf":[{"type":"object","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.key","typeLabel":"string"},"label":{"type":"string","description":"Its name in the app, such as `First name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.label","typeLabel":"string"}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0","typeLabel":"object"},{"type":"null","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`."},"label":{"type":"string","description":"Its name in the app, such as `First name`."}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion","typeLabel":"object | null"},"message":{"type":"string","description":"A sentence to show a person, such as `fisrt_name isn't a variable. Did you mean First name?`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].message","typeLabel":"string"},"field":{"type":"string","enum":["display_name","task_note"],"description":"Step writes only: the field the token is in.","uniqueKey":"unknown.items.[INDEX].field","typeLabel":"enum\u003cstring>"}},"required":["token","key","reason","suggestion","message"],"uniqueKey":"unknown.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unknown","typeLabel":"object[]"}},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"uniqueKey":"","typeLabel":"Error · object"},"example":{"message":"Internal server error","error":"Internal Server Error","statusCode":500,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"examples":{"Example":{"title":"Example","value":{"message":"Internal server error","error":"Internal Server Error","statusCode":500,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}}},"exampleType":"examples"}},"exampleType":"examples"},"68569edb-b263-4549-a52e-2c40dce35841":{"description":"Bad Gateway. The Salesfinity service behind this endpoint (the Sequencer, or the enrichment service) could not be reached. Retry with exponential backoff; for a write, confirm state with a GET before retrying a create.","headers":{"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}},"content":{"application/json":{"schema":{"type":"object","title":"Error","description":"The error envelope returned by every Salesfinity API error response. The shape is identical across all status codes and all endpoints, and `request_id` is present on every error the API returns.","required":["message","error","statusCode","request_id"],"properties":{"message":{"oneOf":[{"type":"string","description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Stable HTTP reason phrase for the status code, such as `Forbidden`. One exception: a 403 from a `/v2/sequencer` write whose `user_id` has no active plan or seat carries `NO_ACTIVE_PLAN` here. Branch on this rather than on `message`.","example":"Forbidden","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","format":"int32","description":"HTTP status code, repeated in the body so it survives transports that drop it.","example":403,"isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer\u003cint32>"},"request_id":{"type":"string","description":"Identifies the request in Salesfinity's logs; the same value as the `X-Request-Id` response header. Include it when you contact support.","example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"errors":{"type":"array","items":{"type":"string","uniqueKey":"errors.items.[INDEX]","typeLabel":"string"},"description":"Present on a few Sequencer errors, such as a rules-of-engagement policy whose rules fail the catalog check: one entry per problem. Other fields an upstream service sends are passed through unchanged too.","uniqueKey":"errors","typeLabel":"string[]"},"code":{"type":"string","description":"A machine-readable reason, present on a few Sequencer errors. `unknown_variables`: a template, a step's name or a step's note holds a token that is not a variable; `unknown` lists each one.","uniqueKey":"code","typeLabel":"string"},"unknown":{"type":"array","description":"Present when `code` is `unknown_variables`: one entry per distinct token that was refused.","items":{"type":"object","description":"A token in double braces that is not a variable, or cannot be used where it was written.","properties":{"token":{"type":"string","description":"The token as written, braces included, such as `{{fisrt_name}}`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].token","typeLabel":"string"},"key":{"type":"string","description":"What is inside the braces, lower-cased, without the fallback.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].key","typeLabel":"string"},"reason":{"type":"string","enum":["not_a_variable","empty","fallback_too_long","unbalanced","not_allowed_here"],"description":"`not_a_variable`: not a built-in variable, not a custom field your team has, and not an AI line (a misspelt AI line such as `{{ ai:opener }}` lands here too). `empty`: nothing to read, as in `{{}}`, `{{ |x}}` or `{{custom.}}`. `fallback_too_long`: the fallback is over 64 characters. `unbalanced`: braces that do not pair up, as in `{{first_name` or `{{first_name}}}`. `not_allowed_here`: a step's name or note only, for an AI line, or for any variable in an email step's name.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"suggestion":{"oneOf":[{"type":"object","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.key","typeLabel":"string"},"label":{"type":"string","description":"Its name in the app, such as `First name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.label","typeLabel":"string"}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0","typeLabel":"object"},{"type":"null","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`."},"label":{"type":"string","description":"Its name in the app, such as `First name`."}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion","typeLabel":"object | null"},"message":{"type":"string","description":"A sentence to show a person, such as `fisrt_name isn't a variable. Did you mean First name?`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].message","typeLabel":"string"},"field":{"type":"string","enum":["display_name","task_note"],"description":"Step writes only: the field the token is in.","uniqueKey":"unknown.items.[INDEX].field","typeLabel":"enum\u003cstring>"}},"required":["token","key","reason","suggestion","message"],"uniqueKey":"unknown.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unknown","typeLabel":"object[]"}},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"uniqueKey":"","typeLabel":"Error · object"},"example":{"message":"Sequencer service unreachable","error":"Bad Gateway","statusCode":502,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"examples":{"Example":{"title":"Example","value":{"message":"Sequencer service unreachable","error":"Bad Gateway","statusCode":502,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}}},"exampleType":"examples"}},"exampleType":"examples"},"14d3f98d-739c-4362-8988-2119c6796470":{"description":"Gateway Timeout. The Sequencer did not answer within 55 seconds. The work may still have finished, and a failed request frees its Idempotency-Key, so confirm state with a GET before retrying a create; retry reads with backoff.","headers":{"X-Request-Id":{"description":"Identifies the request in Salesfinity's logs, and matches `request_id` in an error body. Echoes the `X-Request-Id` you sent when it is 1 to 128 characters of letters, digits, `.`, `_`, `:` and `-`; otherwise Salesfinity generates one.","schema":{"type":"string"},"example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}},"content":{"application/json":{"schema":{"type":"object","title":"Error","description":"The error envelope returned by every Salesfinity API error response. The shape is identical across all status codes and all endpoints, and `request_id` is present on every error the API returns.","required":["message","error","statusCode","request_id"],"properties":{"message":{"oneOf":[{"type":"string","description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"Human-readable description of the failure. A string for most errors, and an array of strings when request validation fails, with one entry per field that did not validate.","example":"Forbidden resource","isRequired":true,"uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","description":"Stable HTTP reason phrase for the status code, such as `Forbidden`. One exception: a 403 from a `/v2/sequencer` write whose `user_id` has no active plan or seat carries `NO_ACTIVE_PLAN` here. Branch on this rather than on `message`.","example":"Forbidden","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","format":"int32","description":"HTTP status code, repeated in the body so it survives transports that drop it.","example":403,"isRequired":true,"uniqueKey":"statusCode","typeLabel":"integer\u003cint32>"},"request_id":{"type":"string","description":"Identifies the request in Salesfinity's logs; the same value as the `X-Request-Id` response header. Include it when you contact support.","example":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10","isRequired":true,"uniqueKey":"request_id","typeLabel":"string"},"errors":{"type":"array","items":{"type":"string","uniqueKey":"errors.items.[INDEX]","typeLabel":"string"},"description":"Present on a few Sequencer errors, such as a rules-of-engagement policy whose rules fail the catalog check: one entry per problem. Other fields an upstream service sends are passed through unchanged too.","uniqueKey":"errors","typeLabel":"string[]"},"code":{"type":"string","description":"A machine-readable reason, present on a few Sequencer errors. `unknown_variables`: a template, a step's name or a step's note holds a token that is not a variable; `unknown` lists each one.","uniqueKey":"code","typeLabel":"string"},"unknown":{"type":"array","description":"Present when `code` is `unknown_variables`: one entry per distinct token that was refused.","items":{"type":"object","description":"A token in double braces that is not a variable, or cannot be used where it was written.","properties":{"token":{"type":"string","description":"The token as written, braces included, such as `{{fisrt_name}}`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].token","typeLabel":"string"},"key":{"type":"string","description":"What is inside the braces, lower-cased, without the fallback.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].key","typeLabel":"string"},"reason":{"type":"string","enum":["not_a_variable","empty","fallback_too_long","unbalanced","not_allowed_here"],"description":"`not_a_variable`: not a built-in variable, not a custom field your team has, and not an AI line (a misspelt AI line such as `{{ ai:opener }}` lands here too). `empty`: nothing to read, as in `{{}}`, `{{ |x}}` or `{{custom.}}`. `fallback_too_long`: the fallback is over 64 characters. `unbalanced`: braces that do not pair up, as in `{{first_name` or `{{first_name}}}`. `not_allowed_here`: a step's name or note only, for an AI line, or for any variable in an email step's name.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].reason","typeLabel":"enum\u003cstring>"},"suggestion":{"oneOf":[{"type":"object","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.key","typeLabel":"string"},"label":{"type":"string","description":"Its name in the app, such as `First name`.","uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0.label","typeLabel":"string"}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.0","typeLabel":"object"},{"type":"null","description":"The closest variable, within 2 edits: built-in variables first, then your team's custom fields. Null when nothing is close, which is common for a `custom.\u003cfield>`.","properties":{"key":{"type":"string","description":"The variable's key, such as `first_name`."},"label":{"type":"string","description":"Its name in the app, such as `First name`."}},"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"unknown.items.[INDEX].suggestion","typeLabel":"object | null"},"message":{"type":"string","description":"A sentence to show a person, such as `fisrt_name isn't a variable. Did you mean First name?`.","isRequired":true,"uniqueKey":"unknown.items.[INDEX].message","typeLabel":"string"},"field":{"type":"string","enum":["display_name","task_note"],"description":"Step writes only: the field the token is in.","uniqueKey":"unknown.items.[INDEX].field","typeLabel":"enum\u003cstring>"}},"required":["token","key","reason","suggestion","message"],"uniqueKey":"unknown.items.[INDEX]","typeLabel":"object"},"uniqueKey":"unknown","typeLabel":"object[]"}},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"uniqueKey":"","typeLabel":"Error · object"},"example":{"message":"Sequencer service timed out","error":"Gateway Timeout","statusCode":504,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"},"examples":{"Example":{"title":"Example","value":{"message":"Sequencer service timed out","error":"Gateway Timeout","statusCode":504,"request_id":"0f6d3c52-9f3e-4c1a-a4b8-2b1f7e5d9c10"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"d89798b7-2249-48bf-bec9-f116988c3362":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Team-scoped API key generated in the Salesfinity dashboard under Settings → Connections → API \u0026 Webhooks. A missing or invalid key returns HTTP 403.","scopes":[],"schemeName":"ApiKeyAuth"}}},"servers":{"e454be74-cffb-47a4-ba19-76c8aa914a2a":{"url":"https://client-api.salesfinity.co","description":"Production. The only public Salesfinity API host."}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"x-api-key","description":"Team-scoped API key generated in the Salesfinity dashboard under Settings → Connections → API \u0026 Webhooks. A missing or invalid key returns HTTP 403.","scopes":[],"schemeName":"ApiKeyAuth"},"schema":{"title":"x-api-key","type":"string","description":"Team-scoped API key generated in the Salesfinity dashboard under Settings → Connections → API \u0026 Webhooks. A missing or invalid key returns HTTP 403.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"ApiKeyAuth","name":"x-api-key"}],"title":"ApiKeyAuth"}]},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"salesfinity","siteName":"Salesfinity Docs","title":"Preview a draft rule set - Salesfinity Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-16T01:36:38.763Z","originalFileLocation":"api-reference/endpoint/preview-sequencer-policy.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=\"light\"}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=\"Measures what an unsaved set of scenarios would have done to the prospects behind the team\u0026#x27;s 200 most recent enrollments, without saving or enrolling anything. Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose scope includes enrollment are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in unmeasured rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both. verdicts counts allow, warn, block, route and require_approval. An example with the verdict route carries routed_to, the id of the sequence they would have started in. Changes nothing, so it takes no Idempotency-Key. It still requires user_id, and as a POST it counts against the Sequencer writes rate limit.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Salesfinity Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_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/salesfinity/-QoBSwygykESAJIM/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Preview a draft rule set - Salesfinity Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"Measures what an unsaved set of scenarios would have done to the prospects behind the team\u0026#x27;s 200 most recent enrollments, without saving or enrolling anything. Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose scope includes enrollment are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in unmeasured rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both. verdicts counts allow, warn, block, route and require_approval. An example with the verdict route carries routed_to, the id of the sequence they would have started in. Changes nothing, so it takes no Idempotency-Key. It still requires user_id, and as a POST it counts against the Sequencer writes rate limit.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Salesfinity Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://docs.salesfinity.ai/images/og.jpg\">\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=\"Preview a draft rule set - Salesfinity Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Measures what an unsaved set of scenarios would have done to the prospects behind the team\u0026#x27;s 200 most recent enrollments, without saving or enrolling anything. Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose scope includes enrollment are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in unmeasured rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both. verdicts counts allow, warn, block, route and require_approval. An example with the verdict route carries routed_to, the id of the sequence they would have started in. Changes nothing, so it takes no Idempotency-Key. It still requires user_id, and as a POST it counts against the Sequencer writes rate limit.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://docs.salesfinity.ai/images/og.jpg\">\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/salesfinity/-QoBSwygykESAJIM/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Salesfinity Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#5429D8\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/endpoint/preview-sequencer-policy.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.salesfinity.ai/#organization\",\"name\":\"Salesfinity Docs\",\"url\":\"https://docs.salesfinity.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/salesfinity/YBsYR5N3Fg_u90-H/logo/light.svg?fit=max\u0026auto=format\u0026n=YBsYR5N3Fg_u90-H\u0026q=85\u0026s=e21e087ae3d1330def1fbf87274af05b\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.salesfinity.ai#website\",\"name\":\"Salesfinity Docs\",\"url\":\"https://docs.salesfinity.ai\",\"publisher\":{\"@id\":\"https://docs.salesfinity.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy#webpage\",\"url\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy\",\"name\":\"Preview a draft rule set\",\"description\":\"Measures what an unsaved set of scenarios would have done to the prospects behind the team's 200 most recent enrollments, without saving or enrolling anything. Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose scope includes enrollment are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in unmeasured rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both. verdicts counts allow, warn, block, route and require_approval. An example with the verdict route carries routed_to, the id of the sequence they would have started in. Changes nothing, so it takes no Idempotency-Key. It still requires user_id, and as a POST it counts against the Sequencer writes rate limit.\",\"dateModified\":\"2026-10-16T01:36:38.763Z\",\"isPartOf\":{\"@id\":\"https://docs.salesfinity.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Sequencer API\",\"item\":\"https://docs.salesfinity.ai/api-reference/endpoint/list-sequencer-sequences\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Policies\",\"item\":\"https://docs.salesfinity.ai/api-reference/endpoint/get-sequencer-policy-catalog\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Preview a draft rule set\",\"item\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy#apireference\",\"headline\":\"Preview a draft rule set\",\"name\":\"Preview a draft rule set\",\"description\":\"Measures what an unsaved set of scenarios would have done to the prospects behind the team's 200 most recent enrollments, without saving or enrolling anything. Run it before saving: a broad rule on the default policy blocks enrollment on every sequence that uses it. Only enabled rules whose scope includes enrollment are measured; step rules are not. The evaluation uses the CRM data already stored for each prospect and makes no CRM calls, so a rule that reads a CRM field not yet fetched for those prospects is listed in unmeasured rather than counted as allowing them. Preview checks the structure of the rules but not whether each action fits its scope; create and update check both. verdicts counts allow, warn, block, route and require_approval. An example with the verdict route carries routed_to, the id of the sequence they would have started in. Changes nothing, so it takes no Idempotency-Key. It still requires user_id, and as a POST it counts against the Sequencer writes rate limit.\",\"url\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy\",\"mainEntityOfPage\":{\"@id\":\"https://docs.salesfinity.ai/api-reference/endpoint/preview-sequencer-policy#webpage\"},\"image\":\"https://docs.salesfinity.ai/images/og.jpg\",\"dateModified\":\"2026-10-16T01:36:38.763Z\",\"publisher\":{\"@id\":\"https://docs.salesfinity.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.salesfinity.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Salesfinity Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Salesfinity Docs","nav":{"global":{"anchors":[{"anchor":"Help Center","icon":"circle-question","href":"https://support.salesfinity.ai"},{"anchor":"Blog","icon":"newspaper","href":"https://salesfinity.ai/blog"},{"anchor":"Status page","icon":"signal","href":"https://salesfinity.statuspage.io"}]},"tabs":[{"tab":"Home","icon":"house","pages":[{"title":"Home","href":""}]},{"tab":"Dialer","icon":"phone","pages":[{"title":"Dialer","href":"/dialer/overview"}]},{"tab":"Coaching","icon":"graduation-cap","pages":[{"title":"Coaching","href":"/coaching/overview"}]},{"tab":"Ari","icon":"sparkles","pages":[{"title":"Ari","href":"/ari/overview"}]},{"tab":"Sequencer","icon":"paper-plane","pages":[{"title":"Sequencer","href":"/sequencer/overview"}]},{"tab":"Use cases","icon":"lightbulb","pages":[{"title":"Use cases","href":"/tutorials/overview"}]},{"tab":"Integrations","icon":"plug","pages":[{"title":"Integrations","href":"/integrations/overview"}]},{"tab":"Developers","icon":"code","groups":[{"group":"Get started","pages":[{"title":"Build on Salesfinity","sidebarTitle":"Developer portal","href":"/developers"},{"title":"API Reference","href":"/api-reference/introduction"},{"title":"Handle API errors","sidebarTitle":"Errors","href":"/api-reference/errors"},{"title":"Stay under the rate limits","sidebarTitle":"Rate limits","href":"/api-reference/rate-limits"},{"title":"Run a sequence over the API","href":"/sequencer/api-quickstart"},{"title":"API changelog","sidebarTitle":"API changelog","href":"/changelog"}]},{"group":"MCP server","pages":[{"title":"Use Salesfinity in Claude and other AI tools","sidebarTitle":"MCP overview","href":"/mcp/overview"},{"title":"Connect Salesfinity to Claude","sidebarTitle":"Claude","href":"/mcp/claude-ai"},{"title":"Connect Salesfinity to Claude Code","sidebarTitle":"Claude Code","href":"/mcp/claude-code"},{"title":"Connect Cursor, Windsurf and other MCP clients","sidebarTitle":"Other clients","href":"/mcp/other-clients"}]},{"group":"MCP reference","pages":[{"title":"MCP tool reference","sidebarTitle":"Tool reference","href":"/mcp/tools"},{"title":"MCP Sequencer tools","sidebarTitle":"Sequencer tools","href":"/mcp/sequencer-tools"}]},{"group":"MCP use cases","pages":[{"title":"Put Claude to work on your sales data","sidebarTitle":"Use cases","href":"/mcp/use-cases/overview"},{"title":"Coach and report on your team with Claude","sidebarTitle":"For managers","href":"/mcp/use-cases/managers"},{"title":"Coach yourself and plan your day with Claude","sidebarTitle":"For reps","href":"/mcp/use-cases/reps"},{"title":"Build reports and clean up lists with Claude","sidebarTitle":"For everyone","href":"/mcp/use-cases/shared"}]},{"group":"Dialer API","pages":[{"group":"Contact lists","pages":[{"title":"List contact lists","openapi":"GET /v1/contact-lists/csv","href":"/api-reference/endpoint/get-contact-lists-csv"},{"title":"Get a contact list","openapi":"GET /v1/contact-lists/csv/{id}","href":"/api-reference/endpoint/get-contact-list-by-id"},{"title":"Create a contact list","openapi":"POST /v1/contact-lists","href":"/api-reference/endpoint/create-list"},{"title":"Add a contact to a list","openapi":"POST /v1/contact-lists/{id}","href":"/api-reference/endpoint/add-contact"},{"title":"Remove a contact from a list","openapi":"DELETE /v1/contact-lists/{id}/contacts/{contactId}","href":"/api-reference/endpoint/remove-contact"},{"title":"Merge contact lists","openapi":"POST /v1/contact-lists/{id}/merge","href":"/api-reference/endpoint/merge-lists"},{"title":"Delete a contact list","openapi":"DELETE /v1/contact-lists/csv/{id}","href":"/api-reference/endpoint/delete-contact-list"},{"title":"Reimport a contact list into the dialing queue","openapi":"POST /v1/contact-lists/csv/{id}/reimport","href":"/api-reference/endpoint/reimport-contacts"}]},{"group":"Notes","pages":[{"title":"Create a note","openapi":"POST /v2/notes","href":"/api-reference/endpoint/create-note"},{"title":"List notes","openapi":"GET /v2/notes","href":"/api-reference/endpoint/list-notes"},{"title":"Update a note","openapi":"PATCH /v2/notes/{id}","href":"/api-reference/endpoint/update-note"},{"title":"Delete a note","openapi":"DELETE /v2/notes/{id}","href":"/api-reference/endpoint/delete-note"},{"title":"Pin or unpin a note","openapi":"POST /v2/notes/{id}/pin","href":"/api-reference/endpoint/pin-note"}]},{"group":"Snoozed contacts","pages":[{"title":"List snoozed contacts","openapi":"GET /v1/snoozed-contacts","href":"/api-reference/endpoint/get-snoozed-contacts"},{"title":"Get a snoozed contact","openapi":"GET /v1/snoozed-contacts/{id}","href":"/api-reference/endpoint/get-snoozed-contact-by-id"},{"title":"Get a snoozed contact by LinkedIn username","openapi":"GET /v1/snoozed-contacts/by-linkedin/{username}","href":"/api-reference/endpoint/get-snoozed-contact-by-linkedin"},{"title":"Update a snoozed contact","openapi":"PUT /v1/snoozed-contacts/{id}","href":"/api-reference/endpoint/update-snoozed-contact"},{"title":"Delete a snoozed contact","openapi":"DELETE /v1/snoozed-contacts/{id}","href":"/api-reference/endpoint/delete-snoozed-contact"}]},{"group":"Custom fields","pages":[{"title":"List custom field mappings","openapi":"GET /v1/custom-fields","href":"/api-reference/endpoint/get-custom-fields"}]},{"group":"Dispositions","pages":[{"title":"List dispositions","openapi":"GET /v1/dispositions","href":"/api-reference/endpoint/get-dispositions"},{"title":"Get a disposition","openapi":"GET /v1/dispositions/{id}","href":"/api-reference/endpoint/get-disposition-by-id"}]},{"group":"Follow-up tasks","pages":[{"title":"List follow-up tasks","openapi":"GET /v1/follow-up","href":"/api-reference/endpoint/get-follow-ups"}]},{"group":"CRM sequences","pages":[{"title":"List CRM sequences","openapi":"GET /v1/sequences","href":"/api-reference/endpoint/get-sequences"},{"title":"Get a CRM sequence","openapi":"GET /v1/sequences/{id}","href":"/api-reference/endpoint/get-sequence-by-id"}]}]},{"group":"Calls and analytics API","pages":[{"group":"Team and call logs","pages":[{"title":"Get the current team","openapi":"GET /v1/team","href":"/api-reference/endpoint/get-team"},{"title":"List call logs","openapi":"GET /v1/call-log","href":"/api-reference/endpoint/call-log"},{"title":"Get a call log","openapi":"GET /v1/call-log/{id}","href":"/api-reference/endpoint/get-call-log-by-id"}]},{"group":"Scored calls","pages":[{"title":"List scored calls","openapi":"GET /v1/scored-calls","href":"/api-reference/endpoint/scored-calls"},{"title":"Get a scored call","openapi":"GET /v1/scored-calls/{id}","href":"/api-reference/endpoint/get-scored-call-by-id"}]},{"group":"Analytics","pages":[{"title":"Get analytics overview","openapi":"GET /v1/analytics/overview","href":"/api-reference/endpoint/analytics-overview"},{"title":"List call performance by contact list","openapi":"GET /v1/analytics/list-performance","href":"/api-reference/endpoint/analytics-list-performance"},{"title":"List call performance by SDR","openapi":"GET /v1/analytics/sdr-performance","href":"/api-reference/endpoint/analytics-sdr-performance"}]}]},{"group":"Enrichment API","pages":[{"title":"Start an email enrichment","openapi":"POST /v1/api/enrichment/email","href":"/api-reference/endpoint/enrich-email"},{"title":"Get an email enrichment result","openapi":"GET /v1/api/enrichment/email/{id}","href":"/api-reference/endpoint/get-email-enrichment"},{"title":"Start a phone enrichment","openapi":"POST /v1/api/enrichment/phone","href":"/api-reference/endpoint/enrich-phone"},{"title":"Get a phone enrichment result","openapi":"GET /v1/api/enrichment/phone/{id}","href":"/api-reference/endpoint/get-phone-enrichment"},{"title":"Get enrichment credit balance","openapi":"GET /v1/api/enrichment/credits","href":"/api-reference/endpoint/get-enrichment-credits"}]},{"group":"Sequencer API","tag":"Early access","pages":[{"group":"Sequences","pages":[{"title":"List sequences","openapi":"GET /v2/sequencer/sequences","href":"/api-reference/endpoint/list-sequencer-sequences"},{"title":"Create a sequence","openapi":"POST /v2/sequencer/sequences","href":"/api-reference/endpoint/create-sequencer-sequence"},{"title":"Get a sequence","openapi":"GET /v2/sequencer/sequences/{id}","href":"/api-reference/endpoint/get-sequencer-sequence"},{"title":"Update a sequence","openapi":"PATCH /v2/sequencer/sequences/{id}","href":"/api-reference/endpoint/update-sequencer-sequence"},{"title":"Delete a sequence","openapi":"DELETE /v2/sequencer/sequences/{id}","href":"/api-reference/endpoint/delete-sequencer-sequence"},{"title":"Add contacts to a sequence","openapi":"POST /v2/sequencer/sequences/{id}/contacts","href":"/api-reference/endpoint/add-contacts-to-sequencer-sequence"},{"title":"Get sequence analytics","openapi":"GET /v2/sequencer/sequences/{id}/analytics","href":"/api-reference/endpoint/get-sequencer-sequence-analytics"},{"title":"List the people behind an engagement metric","openapi":"GET /v2/sequencer/sequences/{id}/analytics/people","href":"/api-reference/endpoint/list-sequencer-engagement-people"},{"title":"List enrollment refusals","openapi":"GET /v2/sequencer/sequences/{id}/enrollment-attempts","href":"/api-reference/endpoint/list-sequencer-enrollment-attempts"},{"title":"Enable a sequence","openapi":"POST /v2/sequencer/sequences/{id}/enable","href":"/api-reference/endpoint/enable-sequencer-sequence"},{"title":"Disable a sequence","openapi":"POST /v2/sequencer/sequences/{id}/disable","href":"/api-reference/endpoint/disable-sequencer-sequence"},{"title":"Duplicate a sequence","openapi":"POST /v2/sequencer/sequences/{id}/duplicate","href":"/api-reference/endpoint/duplicate-sequencer-sequence"}]},{"group":"Steps","pages":[{"title":"List steps","openapi":"GET /v2/sequencer/sequences/{sequence_id}/steps","href":"/api-reference/endpoint/list-sequencer-steps"},{"title":"Add a step","openapi":"POST /v2/sequencer/sequences/{sequence_id}/steps","href":"/api-reference/endpoint/create-sequencer-step"},{"title":"Reorder steps","openapi":"PUT /v2/sequencer/sequences/{sequence_id}/steps/reorder","href":"/api-reference/endpoint/reorder-sequencer-steps"},{"title":"Get a step","openapi":"GET /v2/sequencer/sequences/{sequence_id}/steps/{step_id}","href":"/api-reference/endpoint/get-sequencer-step"},{"title":"Update a step","openapi":"PATCH /v2/sequencer/sequences/{sequence_id}/steps/{step_id}","href":"/api-reference/endpoint/update-sequencer-step"},{"title":"Delete a step","openapi":"DELETE /v2/sequencer/sequences/{sequence_id}/steps/{step_id}","href":"/api-reference/endpoint/delete-sequencer-step"}]},{"group":"Templates","pages":[{"title":"List email templates","openapi":"GET /v2/sequencer/templates","href":"/api-reference/endpoint/list-sequencer-templates"},{"title":"Create an email template","openapi":"POST /v2/sequencer/templates","href":"/api-reference/endpoint/create-sequencer-template"},{"title":"Get an email template","openapi":"GET /v2/sequencer/templates/{id}","href":"/api-reference/endpoint/get-sequencer-template"},{"title":"Update an email template","openapi":"PATCH /v2/sequencer/templates/{id}","href":"/api-reference/endpoint/update-sequencer-template"},{"title":"Delete an email template","openapi":"DELETE /v2/sequencer/templates/{id}","href":"/api-reference/endpoint/delete-sequencer-template"},{"title":"Preview a rendered template","openapi":"POST /v2/sequencer/templates/{id}/preview","href":"/api-reference/endpoint/preview-sequencer-template"}]},{"group":"Enrollments","pages":[{"title":"List enrollments","openapi":"GET /v2/sequencer/enrollments","href":"/api-reference/endpoint/list-sequencer-enrollments"},{"title":"Un-enroll contacts in bulk","openapi":"POST /v2/sequencer/enrollments/bulk/finish","href":"/api-reference/endpoint/bulk-finish-sequencer-enrollments"},{"title":"Approve held enrollments in bulk","openapi":"POST /v2/sequencer/enrollments/bulk/approve","href":"/api-reference/endpoint/bulk-approve-sequencer-enrollments"},{"title":"Reject held enrollments in bulk","openapi":"POST /v2/sequencer/enrollments/bulk/reject","href":"/api-reference/endpoint/bulk-reject-sequencer-enrollments"},{"title":"Reassign enrollments in bulk","openapi":"POST /v2/sequencer/enrollments/bulk/reassign","href":"/api-reference/endpoint/bulk-reassign-sequencer-enrollments"},{"title":"Move enrollments to another sequence","openapi":"POST /v2/sequencer/enrollments/bulk/move","href":"/api-reference/endpoint/move-sequencer-enrollments"},{"title":"Finish or pause everyone at an account","openapi":"POST /v2/sequencer/enrollments/bulk/account","href":"/api-reference/endpoint/sequencer-account-action"},{"title":"Get an enrollment","openapi":"GET /v2/sequencer/enrollments/{id}","href":"/api-reference/endpoint/get-sequencer-enrollment"},{"title":"List enrollment events","openapi":"GET /v2/sequencer/enrollments/{id}/events","href":"/api-reference/endpoint/list-sequencer-enrollment-events"},{"title":"Pause an enrollment","openapi":"POST /v2/sequencer/enrollments/{id}/pause","href":"/api-reference/endpoint/pause-sequencer-enrollment"},{"title":"Resume an enrollment","openapi":"POST /v2/sequencer/enrollments/{id}/resume","href":"/api-reference/endpoint/resume-sequencer-enrollment"},{"title":"Un-enroll a contact","openapi":"POST /v2/sequencer/enrollments/{id}/finish","href":"/api-reference/endpoint/finish-sequencer-enrollment"},{"title":"Retry a failed enrollment","openapi":"POST /v2/sequencer/enrollments/{id}/retry","href":"/api-reference/endpoint/retry-sequencer-enrollment"},{"title":"Reassign an enrollment","openapi":"POST /v2/sequencer/enrollments/{id}/reassign","href":"/api-reference/endpoint/reassign-sequencer-enrollment"},{"title":"Approve a held enrollment","openapi":"POST /v2/sequencer/enrollments/{id}/approve","href":"/api-reference/endpoint/approve-sequencer-enrollment"},{"title":"Reject a held enrollment","openapi":"POST /v2/sequencer/enrollments/{id}/reject","href":"/api-reference/endpoint/reject-sequencer-enrollment"}]},{"group":"Enrollment runs","pages":[{"title":"Preview an enrollment run","openapi":"POST /v2/sequencer/enrollment-runs/preview","href":"/api-reference/endpoint/preview-sequencer-enrolment"},{"title":"Start an enrollment run","openapi":"POST /v2/sequencer/enrollment-runs","href":"/api-reference/endpoint/start-sequencer-enrolment-run"},{"title":"List enrollment runs","openapi":"GET /v2/sequencer/enrollment-runs","href":"/api-reference/endpoint/list-sequencer-enrolment-runs"},{"title":"Get an enrollment run","openapi":"GET /v2/sequencer/enrollment-runs/{run_id}","href":"/api-reference/endpoint/get-sequencer-enrolment-run"},{"title":"Cancel an enrollment run","openapi":"POST /v2/sequencer/enrollment-runs/{run_id}/cancel","href":"/api-reference/endpoint/cancel-sequencer-enrolment-run"}]},{"group":"Tasks","pages":[{"title":"List tasks","openapi":"GET /v2/sequencer/tasks","href":"/api-reference/endpoint/list-sequencer-tasks"},{"title":"Create a one-off task","openapi":"POST /v2/sequencer/tasks","href":"/api-reference/endpoint/create-sequencer-task"},{"title":"Get a task-queue summary","openapi":"GET /v2/sequencer/tasks/summary","href":"/api-reference/endpoint/get-sequencer-task-summary"},{"title":"Get buying-committee coverage","openapi":"GET /v2/sequencer/tasks/account-coverage","href":"/api-reference/endpoint/get-sequencer-account-coverage"},{"title":"Fill a rep’s dial list from their call tasks","openapi":"POST /v2/sequencer/tasks/materialize-call-list","href":"/api-reference/endpoint/materialize-sequencer-call-list"},{"title":"Create one-off tasks in bulk","openapi":"POST /v2/sequencer/tasks/bulk","href":"/api-reference/endpoint/bulk-create-sequencer-tasks"},{"title":"Skip tasks in bulk","openapi":"POST /v2/sequencer/tasks/bulk/skip","href":"/api-reference/endpoint/bulk-skip-sequencer-tasks"},{"title":"Snooze tasks in bulk","openapi":"POST /v2/sequencer/tasks/bulk/snooze","href":"/api-reference/endpoint/bulk-snooze-sequencer-tasks"},{"title":"Reassign tasks in bulk","openapi":"POST /v2/sequencer/tasks/bulk/reassign","href":"/api-reference/endpoint/bulk-reassign-sequencer-tasks"},{"title":"Get a task","openapi":"GET /v2/sequencer/tasks/{id}","href":"/api-reference/endpoint/get-sequencer-task"},{"title":"Update a task","openapi":"PATCH /v2/sequencer/tasks/{id}","href":"/api-reference/endpoint/update-sequencer-task"},{"title":"Cancel a one-off task","openapi":"DELETE /v2/sequencer/tasks/{id}","href":"/api-reference/endpoint/delete-sequencer-task"},{"title":"List task events","openapi":"GET /v2/sequencer/tasks/{id}/events","href":"/api-reference/endpoint/list-sequencer-task-events"},{"title":"Complete a task","openapi":"POST /v2/sequencer/tasks/{id}/complete","href":"/api-reference/endpoint/complete-sequencer-task"},{"title":"Skip a task","openapi":"POST /v2/sequencer/tasks/{id}/skip","href":"/api-reference/endpoint/skip-sequencer-task"},{"title":"Snooze a task","openapi":"POST /v2/sequencer/tasks/{id}/snooze","href":"/api-reference/endpoint/snooze-sequencer-task"},{"title":"Reassign a task","openapi":"POST /v2/sequencer/tasks/{id}/reassign","href":"/api-reference/endpoint/reassign-sequencer-task"}]},{"group":"Suppression","pages":[{"title":"List suppression entries","openapi":"GET /v2/sequencer/suppression","href":"/api-reference/endpoint/list-sequencer-suppression"},{"title":"Add a suppression entry","openapi":"POST /v2/sequencer/suppression","href":"/api-reference/endpoint/create-sequencer-suppression"},{"title":"Import suppression entries","openapi":"POST /v2/sequencer/suppression/import","href":"/api-reference/endpoint/import-sequencer-suppression"},{"title":"Remove a suppression entry","openapi":"DELETE /v2/sequencer/suppression/{id}","href":"/api-reference/endpoint/delete-sequencer-suppression"}]},{"group":"Policies","pages":[{"title":"Get the rules-of-engagement catalog","openapi":"GET /v2/sequencer/policies/catalog","description":"Returns the vocabulary rules of engagement are built from: scopes, conditions, scenario actions, outcomes and reaction actions, with the scopes each is valid in and the parameters each takes. It includes the call-history conditions (`prior_calls`, `last_call_result`, `had_call_result`) and the `route_to_sequence` action, whose `sequence` parameter has `input: \"sequence\"` and `options_source: \"sequences\"`.\n\nRead it before writing a policy. Create and update validate against the same table, and a rule outside it is refused with 400. Each parameter is described by `key`, `label`, `input`, `required`, `min`, `max` and, for a closed list, `options`. Parameters whose values are team-specific (your CRMs, sequences, call dispositions, reply labels) name an `options_source` instead of listing options. A condition marked `deprecated` still works in existing policies but should not be used in new rules.\n\nThe catalog is the same for every team. Counts against the Sequencer reads [rate limit](/api-reference/rate-limits).","href":"/api-reference/endpoint/get-sequencer-policy-catalog"},{"title":"Preview a draft rule set","openapi":"POST /v2/sequencer/policies/preview","href":"/api-reference/endpoint/preview-sequencer-policy"},{"title":"List rules-of-engagement policies","openapi":"GET /v2/sequencer/policies","description":"Returns every rules-of-engagement policy on the team as a plain array, not paginated: the default first, then the rest by name.\n\nEach policy carries `sequence_count`, how many sequences run under it; the default also counts every sequence that names no policy. A team always has exactly one default. If it has none yet, this call creates it, named \"Team default\", with the starting rules described in [Rules of engagement](/sequencer/rules-of-engagement#the-team-default). Counts against the Sequencer reads [rate limit](/api-reference/rate-limits).","href":"/api-reference/endpoint/list-sequencer-policies"},{"title":"Create a rules-of-engagement policy","openapi":"POST /v2/sequencer/policies","href":"/api-reference/endpoint/create-sequencer-policy"},{"title":"Get a rules-of-engagement policy","openapi":"GET /v2/sequencer/policies/{id}","href":"/api-reference/endpoint/get-sequencer-policy"},{"title":"Update a rules-of-engagement policy","openapi":"PATCH /v2/sequencer/policies/{id}","href":"/api-reference/endpoint/update-sequencer-policy"},{"title":"Delete a rules-of-engagement policy","openapi":"DELETE /v2/sequencer/policies/{id}","href":"/api-reference/endpoint/delete-sequencer-policy"},{"title":"Make a policy the team default","openapi":"POST /v2/sequencer/policies/{id}/default","href":"/api-reference/endpoint/set-default-sequencer-policy"}]},{"group":"Settings and mailboxes","pages":[{"title":"Get sequencer settings","openapi":"GET /v2/sequencer/settings","href":"/api-reference/endpoint/get-sequencer-settings"},{"title":"List sending mailboxes","openapi":"GET /v2/sequencer/email-accounts","href":"/api-reference/endpoint/list-sequencer-mailboxes"},{"title":"Get a sending mailbox","openapi":"GET /v2/sequencer/email-accounts/{id}","href":"/api-reference/endpoint/get-sequencer-mailbox"}]}]}]},{"tab":"Help","icon":"life-ring","pages":[{"title":"Help","href":"/help/overview"}]}]},"title":"Preview a draft rule set - Salesfinity Docs","buildId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","deploymentId":"dpl_DFJrtvUi8HS5F9nkooKuDJsuD5BM","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-rfhihCWU.js","utils-BmH1XFxk.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-BcNsxPKB.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BAES3tkd.js","snippetPresets-DCMQBKLP.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-D6l_bzE9.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BOktbnNh.js","shallow-BCs8SgM7.js","getApiPlaygroundDisplay-DEmW5bJB.js","CodeSnippet-CpZOpB9C.js","CodeSnippets-BOBDqibl.js","Page-D5fEM6aW.js","getPastedJson-DH2JBvmr.js","icon-BBJH-kKh.js","MethodPill-D2Sd5NLC.js","DuplicateIcon-CGgfL2qN.js","createIcon-BKudBBzi.js","DynamicMarkdown-85clUA0i.js","SectionHeading-D0JiMgDx.js","axios-vUo_bRtp.js","Markdown-Cfiy0xZO.js","clsx-rL8ZCCw4.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-aeztFa9U.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-BywkCr5C.js"]}