This pricing configuration applies to all leads submitted to this flow. Pricing determines the value of
the purchase_price and cost property on the source event recorded when a lead is submitted.
Each price is evaluated and the last price for which all rules match will determine the amount used
for the purchase_price and cost. If none of these prices match for a particular lead, source pricing
will be evaluated. If no price matches, the price properties on the source event will be set to 0.
Firehose configuration for exporting event data to cloud storage. Supports a legacy flat format (AWS S3 only) and a service-based format that allows multiple cloud storage providers.
Not available yet. Metadata on a flow, with the same keys and limits as Metadata.
managed_by records what manages the flow; absent means the account does.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"ActiveProspect Developer Documentation","colors":{"primary":"#22a7f0","light":"#79caf6","dark":"#22a7f0"},"logo":{"light":"https://mintcdn.com/activeprospectinc/ttzTIJYOTNQPAJMy/logo/activeprospect_logo.svg?fit=max\u0026auto=format\u0026n=ttzTIJYOTNQPAJMy\u0026q=85\u0026s=9c7503c7631642aa1f7288ae35cc02cc","dark":"https://mintcdn.com/activeprospectinc/ttzTIJYOTNQPAJMy/logo/activeprospect_whiteblue.svg?fit=max\u0026auto=format\u0026n=ttzTIJYOTNQPAJMy\u0026q=85\u0026s=3df29616a4d6781de4873141e49ca8e0"},"favicon":"https://mintcdn.com/activeprospectinc/ybHg7UeILJeU2Jw-/favicon.png?fit=max\u0026auto=format\u0026n=ybHg7UeILJeU2Jw-\u0026q=85\u0026s=95060b05f4b73bb5ad4a373e19c17430","navbar":{"links":[{"href":"https://support.activeprospect.com/hc/en-us","label":"Support"}],"primary":{"type":"button","label":"Sign in to ActiveProspect","href":"https://account.activeprospect.com"}},"footer":{"socials":{"facebook":"https://www.facebook.com/activeprospect","x":"https://twitter.com/activeprospect","instagram":"https://www.instagram.com/activeprospectinc","linkedin":"https://www.linkedin.com/company/activeprospect","youtube":"https://www.youtube.com/channel/UCN_HLECy6KzYhFfIyLM50rQ","github":"https://github.com/activeprospect"},"links":[{"header":"Customers","items":[{"label":"Knowledge Base","href":"https://support.activeprospect.com/hc/en-us"},{"label":"Start Certifying your Leads","href":"https://account.activeprospect.com/register/trustedform/certify"},{"label":"Product What's New","href":"https://whatsnew.activeprospect.com/"},{"label":"Platform Status","href":"https://status.activeprospect.com/"},{"label":"Integrations","href":"https://activeprospect.com/integrations"},{"label":"Add-ons","href":"https://activeprospect.com/leadconduit/add-on-services"},{"label":"Support Plans","href":"https://activeprospect.com/support-plans"}]},{"header":"Resources","items":[{"label":"TrustedForm Cert Demo","href":"https://activeprospect.com/products/trustedform-demo"},{"label":"Talk to an Expert","href":"https://activeprospect.com/get-demo"},{"label":"Blog","href":"https://activeprospect.com/blog"},{"label":"InsideCBM","href":"https://activeprospect.com/inside-cbm"},{"label":"Glossary","href":"https://activeprospect.com/glossary"},{"label":"TCPA Compliance","href":"https://activeprospect.com/tcpa-compliance"},{"label":"Ping Pick Post","href":"https://activeprospect.com/ping-pick-post"}]},{"header":"Company","items":[{"label":"About Us","href":"https://activeprospect.com/about-us"},{"label":"Conferences and Events","href":"https://activeprospect.com/activeprospect-events"},{"label":"Careers","href":"https://activeprospect.com/careers"},{"label":"Security","href":"https://activeprospect.com/security"},{"label":"Security Information Portal","href":"https://security.activeprospect.com/"},{"label":"Contact Us","href":"https://activeprospect.com/contact-us"}]},{"header":"Legal","items":[{"label":"Privacy Policy","href":"https://activeprospect.com/privacy-policy"},{"label":"TrustedForm Privacy Policy","href":"https://activeprospect.com/trustedform-privacy-notice"},{"label":"Privacy Notice for California Residents","href":"https://activeprospect.com/privacy-notice-california"},{"label":"Terms of Service","href":"https://activeprospect.com/terms-of-service"},{"label":"TrustedForm Certify EULA","href":"https://activeprospect.com/trustedform-eula"}]}]},"seo":{"metatags":{"canonical":"https://developers.activeprospect.com"}},"contextual":{"options":["copy","view","chatgpt","claude","perplexity","mcp","cursor","vscode"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"activeprospectinc","hasAudioNarration":false,"actualSubdomain":"activeprospectinc","customDomains":["developers.activeprospect.com"],"gitSource":{"type":"github","owner":"activeprospect","repo":"documentation","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aea11512d9111c67b18d575","collectionId":"7533e224-8cf8-49b6-b7a8-e85a461a93bd","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aea11512d9111c67b18d575"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"REMOVE_BRANDING":{"status":"ENABLED"},"CONTEXTUAL_FEEDBACK":{"status":"ENABLED"},"CODE_SNIPPET_FEEDBACK":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6aea11512d9111c67b18d575","clientVersion":"0.0.4054","searchFilterCounts":[{"language":"default","tag":"API Documentation","count":115},{"language":"default","tag":"LeadConduit","count":99},{"language":"default","tag":"API Endpoints","count":92},{"language":"default","tag":"TrustedForm","count":26},{"language":"default","tag":"Flows","count":18},{"language":"default","tag":"TrustedForm API 4.0","count":11},{"language":"default","tag":"Account","count":9},{"language":"default","tag":"Fields","count":9},{"language":"default","tag":"Caps and Limits","count":8},{"language":"default","tag":"Operations","count":8}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":".black-headline{color:#000;font-weight:700;font-size:18px}.tfbody{border:1px solid #000;background-color:#9bcae3;font-family:\"proxima nova\",sans-serif;color:#131718;width:670px;margin:0 auto;padding:20px;font-size:18px}.tfbody input{background-color:#6fb3c1;display:block;margin:10px 0;padding:6px 0;font-size:14px}.tfbody input[type=checkbox]{display:inline}.tfbody input[type=email],.tfbody input[type=password],.tfbody textarea{color:#fff;min-width:90%}.tfbody input[type=text]{color:#fff;min-width:90%;width:200px}.tfbody a{color:#fff}.tfbody .consent_copy{margin:auto;width:80%}.tfbody .form_field_hldr_hldr{width:100%;padding:12px}.tfbody .form_field_hldr{width:44%;display:inline-block}.check-wrapper{padding:6px}#test-form{margin:auto}#consent_tag_target{color:#00008b;width:100%;text-align:center;margin:6px;height:2rem}.indentpar{display:inline}.indented{margin-left:22px;margin-top:-28px;line-height:22px}[data-tf-element-role=\"\"],[data-tf-element-role=consent-language],[data-tf-element-role=offer]{border:2px solid #9bcae3}[data-tf-element-role=offer]:hover{border:2px solid #ff0}[data-tf-element-role=consent-language]:hover{border:2px solid #adff2f}.consent-hilight>* [data-tf-element-role]:not([data-tf-element-role=offer]):not([data-tf-element-role=consent-language]){background-color:inherit;box-shadow:0 0 1px 1px #8a2be2}.consent-hilight>[data-tf-element-role]:not([data-tf-element-role=offer]):not([data-tf-element-role=consent-language]){background-color:#ff0!important;box-shadow:0 0 1px 1px #8a2be2}[data-tf-element-role]:not([data-tf-element-role=offer]):not([data-tf-element-role=consent-language]):hover{background-color:#ff0}"}],"page":{"pagePath":"api-reference/leadconduit/flows/flow","slug":"/api-reference/leadconduit/flows/flow","pageMetadata":{"openapi-schema":"Flow","title":null,"description":null,"href":"/api-reference/leadconduit/flows/flow"},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"openapi-schema":"Flow","title":null,"description":null,"href":"/api-reference/leadconduit/flows/flow"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"schemaData":{"x-tags":["Flows"],"type":"object","summary":"Flows define the complete processing pipeline for lead submissions, from data ingestion through delivery. \nEach flow creates a configurable handler that processes leads through a series of middleware steps in sequence.\n","properties":{"name":{"type":"string","description":"The name of the flow","minLength":1,"example":"Sales Leads","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"enabled":{"type":"boolean","description":"Disabling a flow will prevent any processing of lead submissions. Submission will result in an error outcome.","example":true,"isRequired":true,"uniqueKey":"enabled","typeLabel":"boolean"},"fields":{"type":"array","description":"The list of fields (IDs) representing the lead to be processed by this flow.","items":{"type":"string","description":"The required alphanumeric identifier of the field. Custom fields have an account-specific suffix (e.g. '_acme')","pattern":"^[a-z0-9][a-z0-9._]*$","examples":["first_name","last_name","email","phone_1"],"uniqueKey":"fields.items.[INDEX]","typeLabel":"string"},"example":["first_name","last_name","email","phone_1","address_1","city","state","postal_code","trustedform_cert_url"],"isRequired":true,"uniqueKey":"fields","typeLabel":"string[]"},"sources":{"type":"array","description":"Flows accommodate multiple lead sources. Each source has:\n- **Entity reference** - Identifies the submitting party\n- **Inbound mappings** - Field name transformations specific to that source\n- **Authentication settings** - Credentials and security requirements\n- **Acceptance Criteria** - Source-specific rules that must pass in order to continue processing a lead \n- **Pricing configuration** - Source-specific cost calculations\n- **Caps** - Source-specific caps\n","items":{"type":"object","properties":{"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"sources.items.[INDEX].integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"isRequired":true,"uniqueKey":"sources.items.[INDEX].integration","typeLabel":"object"},"entity":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for an entity","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"sources.items.[INDEX].entity.id","typeLabel":"string"},"name":{"type":"string","readOnly":true,"isRequired":true,"uniqueKey":"sources.items.[INDEX].entity.name","typeLabel":"string"},"time_zone":{"type":"string","example":"America/New_York","uniqueKey":"sources.items.[INDEX].entity.time_zone","typeLabel":"string"}},"additionalProperties":false,"required":["id","name"],"isRequired":true,"uniqueKey":"sources.items.[INDEX].entity","typeLabel":"object"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"sources.items.[INDEX].id","typeLabel":"string"},"acceptance_criteria":{"title":"Acceptance Criteria","type":"object","properties":{"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for a lead to be accepted","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.rule_set","typeLabel":"Rule Set · object"},"outcome":{"type":"string","description":"When the rule set fails, `success`, `failure` or `error` is returned to the source that submitted the lead","enum":["success","failure","error"],"example":"failure","isRequired":true,"uniqueKey":"sources.items.[INDEX].acceptance_criteria.outcome","typeLabel":"enum\u003cstring>"},"reason":{"type":"string","title":"Template","description":"When the outcome is `failure`, this is the reason to provide to the source","x-tags":["Templates"],"example":"Lead must live in TX","uniqueKey":"sources.items.[INDEX].acceptance_criteria.reason","typeLabel":"string"}},"additionalProperties":false,"required":["outcome","rule_set"],"description":"Acceptance criteria specifies the kinds of leads that a source or sources must provide in a flow. Acceptance criteria can be configured at both a flow level and a source level. When a source submits a lead, the flow-level acceptance criteria rule set is evaluated first, then any source-level acceptance criteria. If the rule sets pass, then the lead is allowed to progress on in the flow. But if either rule set fails, then the source is immediately given a response and no further processing takes place in the flow for that lead.\n","uniqueKey":"sources.items.[INDEX].acceptance_criteria","typeLabel":"Acceptance Criteria · object"},"feedback":{"description":"Feedback specifies the configuration for receiving and sending feedback\nabout a lead. When receiving feedback from a recipient, the `rule_set`\nmust pass. If it does not, a \"failure\" Feedback Received Event is\ncreated. When sending feedback to a source, the `rule_set` must pass. If\nit does not, a \" skip\" Feedback Sent Event is created.\n","properties":{"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"sources.items.[INDEX].feedback.integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].feedback.integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"description":"The integration to be used for the feedback","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.integration","typeLabel":"object"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"If the rules fail the feedback is not performed","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].feedback.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"sources.items.[INDEX].feedback.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"sources.items.[INDEX].feedback.rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["integration"],"type":"object","uniqueKey":"sources.items.[INDEX].feedback","typeLabel":"object"},"caps":{"oneOf":[{"type":"null","description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","uniqueKey":"sources.items.[INDEX].caps.oneOf.0","typeLabel":"null"},{"type":"array","items":{"x-tags":["Caps and Limits"],"type":"object","description":"A cap allows limiting the number of leads sent into or out of a flow. \nIf a lead is successful, it will be counted against the maximum configured leads. \nIf configured, the rule set will be evaluated to determine whether a lead will be counted against the cap.\n","properties":{"id":{"type":"string","description":"The unique identifier of the cap","pattern":"^[0-9a-fA-F]{24}$","example":"5fd438f91f0d12766e2bfee5","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].id","typeLabel":"string"},"type":{"type":"string","description":"The type of this cap (LeadConduit may eventually support different types of caps)","enum":["volume"],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"name":{"description":"The human-readable name of the cap","type":"string","example":"Monthly leads from TX","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"number","description":"The number of successful leads that will be accepted","example":1200,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].maximum","typeLabel":"number"},"duration":{"type":"number","description":"The number duration_units for which the cap persists","minimum":1,"examples":[1],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].duration","typeLabel":"number"},"duration_units":{"type":"string","description":"The unit of time for which the cap persists","enum":["month","week","day","hour","minute"],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].duration_units","typeLabel":"enum\u003cstring>"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for the lead to count against the cap","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set","typeLabel":"Rule Set · object"},"caps":{"description":"Nested caps evaluated if rules for the parent cap pass","type":"array","items":{"$circularRef":"a0504bde-eae4-48cd-8488-ce131a7ae199"},"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].caps","typeLabel":"array"},"time_zone":{"description":"The time zone in which cap resets","type":"string","example":"America/New_York","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].time_zone","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the cap is met this is the reason (default: 'Cap reached')","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].reason","typeLabel":"string"},"created_at":{"description":"Read-only time the cap was created","type":"string","format":"date-time","example":"2020-11-23T11:41:52Z","uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"sources.items.[INDEX].caps.oneOf.1.items.[INDEX]","typeLabel":"object"},"description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","minItems":1,"uniqueKey":"sources.items.[INDEX].caps.oneOf.1","typeLabel":"object[]"}],"uniqueKey":"sources.items.[INDEX].caps","typeLabel":"null | object[]"},"ping_limits":{"title":"Ping Limits","type":"array","items":{"x-tags":["Caps and Limits"],"title":"Ping Limit","description":"The ping limit configuration is defined in a flow on a source, or directly on the flow itself. The configuration controls the behavior of the ping limit by setting the maximum and the duration. The counter for a ping limit is kept as a standalone record which shares ping limit's ID.","type":"object","properties":{"id":{"type":"string","description":"24 character alpha-numeric BSON identifier","pattern":"^[0-9a-fA-F]{24}$","readOnly":true,"example":"5fd4371e940df5a34a3888b2","uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].id","typeLabel":"string"},"name":{"type":"string","description":"The human-readable name of the ping limit","uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"integer","description":"The number of pings that will be accepted","uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].maximum","typeLabel":"integer"},"duration":{"type":"integer","description":"The number duration_units the ping limit persists for","uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].duration","typeLabel":"integer"},"duration_units":{"type":"string","description":"The unit of time the ping limit persists for: minute, hour, day, week, or month","uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].duration_units","typeLabel":"string"},"time_zone":{"type":"string","description":"The time zone in which ping limit resets","example":"America/New_York","uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].time_zone","typeLabel":"string"},"created_at":{"type":"string","format":"date-time","description":"Read-only time the ping limit was created","readOnly":true,"uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"sources.items.[INDEX].ping_limits.items.[INDEX]","typeLabel":"Ping Limit · object"},"uniqueKey":"sources.items.[INDEX].ping_limits","typeLabel":"Ping Limit · object[]"},"credential_id":{"type":"string","description":"The unique identifier for a credential","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","uniqueKey":"sources.items.[INDEX].credential_id","typeLabel":"string"},"pricing":{"description":"Pricing in LeadConduit automates your financial operations by calculating purchase costs (what you pay lead sellers) and sale prices (what you charge buyers) for every lead. It automates pricing based on dynamic criteria you define, typically reflecting what's in your business agreements.\n\nPricing configurations are primarily an array of prices that can be set to fixed amounts, calculated based on conditional rules, or provided by your own pricing service for each lead. Pricing can be set at the flow, flow source, and recipient step level. \n\nPricing determines the `purchase_price` and `sale_price` properties on events, and consequently the `cost` and `revenue` properties. These properties are available via the statistics API and reporting API. If no pricing is configured, these properties default to `0`. Price is recorded on the lead event, creating a complete audit trail for reconciliation, lead seller payments, and buyer invoicing.\n\n## How Pricing Works\n\n### Two Types of Pricing\n\n**Purchase Pricing**: What you pay lead sellers for leads. Calculated during submission, recorded on source events. Can be fixed per lead seller, dynamic based on lead characteristics, determined by external services, or overridden by sources.\n\n**Sale Pricing**: What you charge buyers for leads. Calculated during delivery, recorded on recipient events. Each buyer can have different pricing for the same lead.\n\n### Purchase Pricing Evaluation Layers\n\nFor purchase pricing, three layers with precedence order (first match wins):\n\n1. **Pricing Service**: Contact an external API for real-time/dynamic pricing with fallback\n2. **Source Pricing Rules**: Source-specific rules that override flow-level pricing \n3. **Flow Pricing Rules**: Base pricing rules when no other pricing applies\n\n### Pricing Rules\n\nPricing rules use LeadConduit's rule engine with **last matching price wins** behavior. This allows general-to-specific pricing where more specific conditions override general ones.\n\n**Limits**: Max $1,000,000, default $0.00, negative prices only via return feedback credits.\n\n**Example**: For prices $10 (base), $15 (CA), $20 (CA + auto), $25 (premium) - a premium auto lead from CA gets $25.\n\n### Pricing Service\n\nExternal APIs enable dynamic pricing based on market conditions, buyer demand, lead quality, or custom algorithms. Services return price and reason; fallback price used if service fails.\n\n### Override Pricing\n\n**Purchase Override**: Sources can specify their own price, bypassing normal purchase pricing calculation. Used for special campaigns, negotiated deals, test leads, or credits.\n\n**Sale Override**: Recipients can specify their own price, bypassing normal sale pricing calculation. Used for custom buyer agreements or special pricing arrangements.\n\n**Technical Note**: When `override: true`, the `prices` array must be empty, null, or undefined. The price will be set to whatever amount is provided by the source or recipient.\n\n## Purchase Pricing\n\nCalculated during lead submission before acceptance criteria. Can be fixed per lead seller, geographic-based, quality-based, or dynamic via external services. Recorded on source events for lead seller reconciliation and margin calculation.\n\n**Common Patterns**:\n- Fixed: $25.00 per lead\n- Geographic: $10 base, $15 for CA/NY/FL, $20 for TX \n- Quality: $5 base + premiums for TrustedForm certified leads, leads with extended data\n- Time-Based - $25 business hours, $30 weekends, $15 late night\n- Dynamic: External service with fallback pricing\n\n## Sale Pricing\n\nConfigured on recipient steps, calculated during delivery after lead acceptance. Each buyer can have different pricing for the same lead. Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Common Patterns**:\n- Fixed: $45.00 per delivered lead\n- Tiered: $30 base, $50 for high loan amounts, $75 for premium credit scores\n- Multi-buyer: $100 exclusive, $25 shared pools\n- Revenue aggregation: Multiple successful deliveries sum to total revenue\n\n## Reporting and Reconciliation\n\n**Key Metrics**: Total spend/revenue by lead seller/buyer, cost/revenue per lead, margin analysis, ROI by lead type.\n\n**Monthly Reconciliation**: \n- Lead seller payments: Sum purchase_price from source events\n- Buyer invoicing: Sum sale_price from successful recipient events\n\n**Revenue from Success**: Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Return Feedback Credits**: Handle quality issues through return feedback mechanism with negative pricing entries for reconciliation.\n\n**Dispute Resolution**: Every event contains pricing configuration, evaluated data, and rule matches for complete audit trail.","type":"object","properties":{"override":{"description":"Allows a source or a recipient to specify the price rather than\nrelying on `prices`\n","type":"boolean","uniqueKey":"sources.items.[INDEX].pricing.override","typeLabel":"boolean"},"prices":{"description":"The list of prices to evaluate for each lead","type":"array","items":{"description":"A price determines the `purchase_price` or `sale_price` for a lead. If\nall rules in the `rule_set` pass, then the appropriate price property\nwill be set equal to the `amount`. When more than one price is\nspecified, the last matching price will be used to set the price\nproperty on the event.\n","type":"object","properties":{"amount":{"description":"The price of the lead in USD","type":"number","exclusiveMinimum":0,"isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].amount","typeLabel":"number"},"id":{"$circularRef":"5d3151ea-7285-4faa-9e58-f06d41c57a09","description":"ID of this price (matches the ID of the corresponding price configuration)\n","uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].id","typeLabel":"any"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The rule set which must pass in order for this price to be\nconsidered\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"required":["amount"],"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing.prices.items.[INDEX]","typeLabel":"object"},"uniqueKey":"sources.items.[INDEX].pricing.prices","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing","typeLabel":"object"},"pricing_service":{"type":"object","title":"Pricing Service Config","description":"The configuration required on a Source or Flow to define a Pricing Service for lead pricing.\n","properties":{"service_id":{"type":"string","description":"The unique identifier for a configured pricing service","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing_service.service_id","typeLabel":"string"},"fallback_price":{"type":"number","isRequired":true,"uniqueKey":"sources.items.[INDEX].pricing_service.fallback_price","typeLabel":"number"}},"required":["service_id","fallback_price"],"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].pricing_service","typeLabel":"Pricing Service Config · object"},"enabled":{"type":"boolean","uniqueKey":"sources.items.[INDEX].enabled","typeLabel":"boolean"},"authentication_required":{"type":"boolean","uniqueKey":"sources.items.[INDEX].authentication_required","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"sources.items.[INDEX].metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"sources.items.[INDEX].metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":true,"required":["integration","entity"],"uniqueKey":"sources.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"sources","typeLabel":"object[]"},"steps":{"type":"array","description":"After executing acceptance criteria, caps, and pricing, for the source and flow, steps are\nprocessed in order sequentially.\n","items":{"oneOf":[{"type":"object","title":"Calculated Step","description":"A calculated step evaluates rules and templates to set calculated field values on a lead\nbefore continuing to the next step.\n","required":["type","fields"],"properties":{"type":{"type":"string","enum":["calculated"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"fields":{"type":"array","maxItems":50,"items":{"oneOf":[{"type":"object","required":["name","type","rules","fallback"],"properties":{"name":{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.name","typeLabel":"string"},"type":{"type":"string","enum":["number","string"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","maxItems":50,"items":{"type":"object","properties":{"value":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].value","typeLabel":"string"},"rule_set":{"oneOf":[{"type":"object","title":"Rule Set","description":"A rule set is a collection of rules to evaluate. The `op` property determines whether all rules must pass (`and`) or just one of them must pass (`or`) in order for the rule set to be considered passing.\n","required":["op","rules"],"x-tags":["Rules"],"properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0.id","typeLabel":"string"}},"additionalProperties":false,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.0","typeLabel":"Rule Set · object"},{"type":"null","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].rule_set","typeLabel":"Rule Set · object | null"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX].id","typeLabel":"string"}},"additionalProperties":false,"required":["value","rule_set"],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.rules","typeLabel":"object[]"},"fallback":{"oneOf":[{"type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.fallback.oneOf.0","typeLabel":"string"},{"type":"null","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.fallback.oneOf.1","typeLabel":"null"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.fallback","typeLabel":"string | null"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0.id","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.0","typeLabel":"object"},{"type":"object","required":["calculated_field_id"],"properties":{"calculated_field_id":{"type":"string","description":"24 character alpha-numeric BSON identifier","pattern":"^[0-9a-fA-F]{24}$","readOnly":true,"example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.1.calculated_field_id","typeLabel":"string"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.1.id","typeLabel":"string"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX].oneOf.1","typeLabel":"object"}],"uniqueKey":"steps.items.[INDEX].oneOf.0.fields.items.[INDEX]","typeLabel":"object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.fields","typeLabel":"object[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.id","typeLabel":"string"},"description":{"type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.0.description","typeLabel":"string"},"notes":{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.0.notes","typeLabel":"string"},"enabled":{"type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.0.enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.0","typeLabel":"Calculated Step · object"},{"type":"object","title":"Filter Step","description":"A filter step is used to stop processing a lead from advancing to the\nnext flow step. This is conceptually similar to an email inbox filter.\nIf the lead matches the rules then the flow is stopped, which\neffectively filters out the lead. When a filter step stops the flow, the\nsource receives an immediate response and no further steps are\nprocessed.\n","required":["type","outcome","rule_set"],"properties":{"type":{"description":"The type of the step (always `filter`)","type":"string","enum":["filter"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"outcome":{"description":"When the flow stops, `success`, `failure` or `error` is returned to\nthe source that submitted the lead\n","type":"string","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.outcome","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The flow stops when the rules match the lead","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.rule_set","typeLabel":"Rule Set · object"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this step","uniqueKey":"steps.items.[INDEX].oneOf.1.id","typeLabel":"string"},"description":{"description":"A brief description of what this filter does","type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.1.description","typeLabel":"string"},"notes":{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.1.notes","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the outcome is `failure` or `error`, this is the reason to\nprovide to the source\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.1.reason","typeLabel":"string"},"enabled":{"description":"Whether this step should be run when processing a lead or not\n","type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.1.enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.1","typeLabel":"Filter Step · object"},{"type":"object","title":"Recipient Step","description":"A recipient step is used to send leads out of LeadConduit. It is used to connect with add-on services or to \ninvoke any outbound integration.\n","required":["type","entity","integration"],"properties":{"type":{"type":"string","enum":["recipient"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.type","typeLabel":"enum\u003cstring>"},"entity":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for an entity","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.entity.id","typeLabel":"string"},"name":{"type":"string","readOnly":true,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.entity.name","typeLabel":"string"},"time_zone":{"type":"string","example":"America/New_York","uniqueKey":"steps.items.[INDEX].oneOf.2.entity.time_zone","typeLabel":"string"}},"additionalProperties":false,"required":["id","name"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.entity","typeLabel":"object"},"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.integration","typeLabel":"object"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.id","typeLabel":"string"},"description":{"type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.2.description","typeLabel":"string"},"notes":{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.2.notes","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"A rule set is a collection of rules to evaluate. The `op` property determines whether all rules must pass (`and`) or just one of them must pass (`or`) in order for the rule set to be considered passing.\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.2.rule_set","typeLabel":"Rule Set · object"},"feedback":{"description":"Feedback specifies the configuration for receiving and sending feedback\nabout a lead. When receiving feedback from a recipient, the `rule_set`\nmust pass. If it does not, a \"failure\" Feedback Received Event is\ncreated. When sending feedback to a source, the `rule_set` must pass. If\nit does not, a \" skip\" Feedback Sent Event is created.\n","properties":{"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"description":"The integration to be used for the feedback","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.integration","typeLabel":"object"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"If the rules fail the feedback is not performed","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.2.feedback.rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["integration"],"type":"object","uniqueKey":"steps.items.[INDEX].oneOf.2.feedback","typeLabel":"object"},"caps":{"oneOf":[{"type":"null","description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.0","typeLabel":"null"},{"type":"array","items":{"x-tags":["Caps and Limits"],"type":"object","description":"A cap allows limiting the number of leads sent into or out of a flow. \nIf a lead is successful, it will be counted against the maximum configured leads. \nIf configured, the rule set will be evaluated to determine whether a lead will be counted against the cap.\n","properties":{"id":{"type":"string","description":"The unique identifier of the cap","pattern":"^[0-9a-fA-F]{24}$","example":"5fd438f91f0d12766e2bfee5","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].id","typeLabel":"string"},"type":{"type":"string","description":"The type of this cap (LeadConduit may eventually support different types of caps)","enum":["volume"],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"name":{"description":"The human-readable name of the cap","type":"string","example":"Monthly leads from TX","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"number","description":"The number of successful leads that will be accepted","example":1200,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].maximum","typeLabel":"number"},"duration":{"type":"number","description":"The number duration_units for which the cap persists","minimum":1,"examples":[1],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].duration","typeLabel":"number"},"duration_units":{"type":"string","description":"The unit of time for which the cap persists","enum":["month","week","day","hour","minute"],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].duration_units","typeLabel":"enum\u003cstring>"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for the lead to count against the cap","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].rule_set","typeLabel":"Rule Set · object"},"caps":{"description":"Nested caps evaluated if rules for the parent cap pass","type":"array","items":{"$circularRef":"a0504bde-eae4-48cd-8488-ce131a7ae199"},"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].caps","typeLabel":"array"},"time_zone":{"description":"The time zone in which cap resets","type":"string","example":"America/New_York","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].time_zone","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the cap is met this is the reason (default: 'Cap reached')","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].reason","typeLabel":"string"},"created_at":{"description":"Read-only time the cap was created","type":"string","format":"date-time","example":"2020-11-23T11:41:52Z","uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1.items.[INDEX]","typeLabel":"object"},"description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","minItems":1,"uniqueKey":"steps.items.[INDEX].oneOf.2.caps.oneOf.1","typeLabel":"object[]"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.caps","typeLabel":"null | object[]"},"pricing":{"description":"Pricing in LeadConduit automates your financial operations by calculating purchase costs (what you pay lead sellers) and sale prices (what you charge buyers) for every lead. It automates pricing based on dynamic criteria you define, typically reflecting what's in your business agreements.\n\nPricing configurations are primarily an array of prices that can be set to fixed amounts, calculated based on conditional rules, or provided by your own pricing service for each lead. Pricing can be set at the flow, flow source, and recipient step level. \n\nPricing determines the `purchase_price` and `sale_price` properties on events, and consequently the `cost` and `revenue` properties. These properties are available via the statistics API and reporting API. If no pricing is configured, these properties default to `0`. Price is recorded on the lead event, creating a complete audit trail for reconciliation, lead seller payments, and buyer invoicing.\n\n## How Pricing Works\n\n### Two Types of Pricing\n\n**Purchase Pricing**: What you pay lead sellers for leads. Calculated during submission, recorded on source events. Can be fixed per lead seller, dynamic based on lead characteristics, determined by external services, or overridden by sources.\n\n**Sale Pricing**: What you charge buyers for leads. Calculated during delivery, recorded on recipient events. Each buyer can have different pricing for the same lead.\n\n### Purchase Pricing Evaluation Layers\n\nFor purchase pricing, three layers with precedence order (first match wins):\n\n1. **Pricing Service**: Contact an external API for real-time/dynamic pricing with fallback\n2. **Source Pricing Rules**: Source-specific rules that override flow-level pricing \n3. **Flow Pricing Rules**: Base pricing rules when no other pricing applies\n\n### Pricing Rules\n\nPricing rules use LeadConduit's rule engine with **last matching price wins** behavior. This allows general-to-specific pricing where more specific conditions override general ones.\n\n**Limits**: Max $1,000,000, default $0.00, negative prices only via return feedback credits.\n\n**Example**: For prices $10 (base), $15 (CA), $20 (CA + auto), $25 (premium) - a premium auto lead from CA gets $25.\n\n### Pricing Service\n\nExternal APIs enable dynamic pricing based on market conditions, buyer demand, lead quality, or custom algorithms. Services return price and reason; fallback price used if service fails.\n\n### Override Pricing\n\n**Purchase Override**: Sources can specify their own price, bypassing normal purchase pricing calculation. Used for special campaigns, negotiated deals, test leads, or credits.\n\n**Sale Override**: Recipients can specify their own price, bypassing normal sale pricing calculation. Used for custom buyer agreements or special pricing arrangements.\n\n**Technical Note**: When `override: true`, the `prices` array must be empty, null, or undefined. The price will be set to whatever amount is provided by the source or recipient.\n\n## Purchase Pricing\n\nCalculated during lead submission before acceptance criteria. Can be fixed per lead seller, geographic-based, quality-based, or dynamic via external services. Recorded on source events for lead seller reconciliation and margin calculation.\n\n**Common Patterns**:\n- Fixed: $25.00 per lead\n- Geographic: $10 base, $15 for CA/NY/FL, $20 for TX \n- Quality: $5 base + premiums for TrustedForm certified leads, leads with extended data\n- Time-Based - $25 business hours, $30 weekends, $15 late night\n- Dynamic: External service with fallback pricing\n\n## Sale Pricing\n\nConfigured on recipient steps, calculated during delivery after lead acceptance. Each buyer can have different pricing for the same lead. Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Common Patterns**:\n- Fixed: $45.00 per delivered lead\n- Tiered: $30 base, $50 for high loan amounts, $75 for premium credit scores\n- Multi-buyer: $100 exclusive, $25 shared pools\n- Revenue aggregation: Multiple successful deliveries sum to total revenue\n\n## Reporting and Reconciliation\n\n**Key Metrics**: Total spend/revenue by lead seller/buyer, cost/revenue per lead, margin analysis, ROI by lead type.\n\n**Monthly Reconciliation**: \n- Lead seller payments: Sum purchase_price from source events\n- Buyer invoicing: Sum sale_price from successful recipient events\n\n**Revenue from Success**: Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Return Feedback Credits**: Handle quality issues through return feedback mechanism with negative pricing entries for reconciliation.\n\n**Dispute Resolution**: Every event contains pricing configuration, evaluated data, and rule matches for complete audit trail.","type":"object","properties":{"override":{"description":"Allows a source or a recipient to specify the price rather than\nrelying on `prices`\n","type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.override","typeLabel":"boolean"},"prices":{"description":"The list of prices to evaluate for each lead","type":"array","items":{"description":"A price determines the `purchase_price` or `sale_price` for a lead. If\nall rules in the `rule_set` pass, then the appropriate price property\nwill be set equal to the `amount`. When more than one price is\nspecified, the last matching price will be used to set the price\nproperty on the event.\n","type":"object","properties":{"amount":{"description":"The price of the lead in USD","type":"number","exclusiveMinimum":0,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].amount","typeLabel":"number"},"id":{"$circularRef":"5d3151ea-7285-4faa-9e58-f06d41c57a09","description":"ID of this price (matches the ID of the corresponding price configuration)\n","uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].id","typeLabel":"any"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The rule set which must pass in order for this price to be\nconsidered\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"required":["amount"],"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices.items.[INDEX]","typeLabel":"object"},"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing.prices","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.pricing","typeLabel":"object"},"enabled":{"type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.2.enabled","typeLabel":"boolean"},"retry_enabled":{"type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.2.retry_enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.2.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.2","typeLabel":"Recipient Step · object"},{"type":"object","title":"Distribution Step","description":"A distribution step is a container for multiple recipient steps with a configurable distribution method.\nDuring handler construction, distribution steps are unwound into individual recipient steps. For waterfall\ndistribution, recipients are executed sequentially and each subsequent recipient only runs if all prior\nrecipients did not succeed. For broadcast distribution, all recipients are executed.\n","required":["type","distribution_method","lead_type","steps"],"properties":{"type":{"type":"string","enum":["distribution"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.type","typeLabel":"enum\u003cstring>"},"distribution_method":{"description":"The method used to distribute leads to the recipient steps within this distribution.\n\"Waterfall\" sends to each recipient in order until one succeeds. \"Send to each recipient\"\nsends to all recipients.\n","type":"string","enum":["Send to each recipient","Waterfall"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.distribution_method","typeLabel":"enum\u003cstring>"},"lead_type":{"description":"Whether the lead is shared across multiple buyers or exclusive to a single buyer.\n","type":"string","enum":["Shared","Exclusive"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.lead_type","typeLabel":"enum\u003cstring>"},"steps":{"type":"array","items":{"title":"Recipient Step","type":"object","description":"A recipient step is used to send leads out of LeadConduit. It is used to connect with add-on services or to \ninvoke any outbound integration.\n","properties":{"type":{"type":"string","enum":["recipient"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"entity":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for an entity","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].entity.id","typeLabel":"string"},"name":{"type":"string","readOnly":true,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].entity.name","typeLabel":"string"},"time_zone":{"type":"string","example":"America/New_York","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].entity.time_zone","typeLabel":"string"}},"additionalProperties":false,"required":["id","name"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].entity","typeLabel":"object"},"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].integration","typeLabel":"object"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].id","typeLabel":"string"},"description":{"type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].description","typeLabel":"string"},"notes":{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].notes","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"A rule set is a collection of rules to evaluate. The `op` property determines whether all rules must pass (`and`) or just one of them must pass (`or`) in order for the rule set to be considered passing.\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].rule_set","typeLabel":"Rule Set · object"},"feedback":{"description":"Feedback specifies the configuration for receiving and sending feedback\nabout a lead. When receiving feedback from a recipient, the `rule_set`\nmust pass. If it does not, a \"failure\" Feedback Received Event is\ncreated. When sending feedback to a source, the `rule_set` must pass. If\nit does not, a \" skip\" Feedback Sent Event is created.\n","properties":{"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"description":"The integration to be used for the feedback","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.integration","typeLabel":"object"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"If the rules fail the feedback is not performed","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback.rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["integration"],"type":"object","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].feedback","typeLabel":"object"},"caps":{"oneOf":[{"type":"null","description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.0","typeLabel":"null"},{"type":"array","items":{"x-tags":["Caps and Limits"],"type":"object","description":"A cap allows limiting the number of leads sent into or out of a flow. \nIf a lead is successful, it will be counted against the maximum configured leads. \nIf configured, the rule set will be evaluated to determine whether a lead will be counted against the cap.\n","properties":{"id":{"type":"string","description":"The unique identifier of the cap","pattern":"^[0-9a-fA-F]{24}$","example":"5fd438f91f0d12766e2bfee5","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].id","typeLabel":"string"},"type":{"type":"string","description":"The type of this cap (LeadConduit may eventually support different types of caps)","enum":["volume"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"name":{"description":"The human-readable name of the cap","type":"string","example":"Monthly leads from TX","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"number","description":"The number of successful leads that will be accepted","example":1200,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].maximum","typeLabel":"number"},"duration":{"type":"number","description":"The number duration_units for which the cap persists","minimum":1,"examples":[1],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].duration","typeLabel":"number"},"duration_units":{"type":"string","description":"The unit of time for which the cap persists","enum":["month","week","day","hour","minute"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].duration_units","typeLabel":"enum\u003cstring>"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for the lead to count against the cap","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].rule_set","typeLabel":"Rule Set · object"},"caps":{"description":"Nested caps evaluated if rules for the parent cap pass","type":"array","items":{"$circularRef":"a0504bde-eae4-48cd-8488-ce131a7ae199"},"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].caps","typeLabel":"array"},"time_zone":{"description":"The time zone in which cap resets","type":"string","example":"America/New_York","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].time_zone","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the cap is met this is the reason (default: 'Cap reached')","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].reason","typeLabel":"string"},"created_at":{"description":"Read-only time the cap was created","type":"string","format":"date-time","example":"2020-11-23T11:41:52Z","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1.items.[INDEX]","typeLabel":"object"},"description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","minItems":1,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps.oneOf.1","typeLabel":"object[]"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].caps","typeLabel":"null | object[]"},"pricing":{"description":"Pricing in LeadConduit automates your financial operations by calculating purchase costs (what you pay lead sellers) and sale prices (what you charge buyers) for every lead. It automates pricing based on dynamic criteria you define, typically reflecting what's in your business agreements.\n\nPricing configurations are primarily an array of prices that can be set to fixed amounts, calculated based on conditional rules, or provided by your own pricing service for each lead. Pricing can be set at the flow, flow source, and recipient step level. \n\nPricing determines the `purchase_price` and `sale_price` properties on events, and consequently the `cost` and `revenue` properties. These properties are available via the statistics API and reporting API. If no pricing is configured, these properties default to `0`. Price is recorded on the lead event, creating a complete audit trail for reconciliation, lead seller payments, and buyer invoicing.\n\n## How Pricing Works\n\n### Two Types of Pricing\n\n**Purchase Pricing**: What you pay lead sellers for leads. Calculated during submission, recorded on source events. Can be fixed per lead seller, dynamic based on lead characteristics, determined by external services, or overridden by sources.\n\n**Sale Pricing**: What you charge buyers for leads. Calculated during delivery, recorded on recipient events. Each buyer can have different pricing for the same lead.\n\n### Purchase Pricing Evaluation Layers\n\nFor purchase pricing, three layers with precedence order (first match wins):\n\n1. **Pricing Service**: Contact an external API for real-time/dynamic pricing with fallback\n2. **Source Pricing Rules**: Source-specific rules that override flow-level pricing \n3. **Flow Pricing Rules**: Base pricing rules when no other pricing applies\n\n### Pricing Rules\n\nPricing rules use LeadConduit's rule engine with **last matching price wins** behavior. This allows general-to-specific pricing where more specific conditions override general ones.\n\n**Limits**: Max $1,000,000, default $0.00, negative prices only via return feedback credits.\n\n**Example**: For prices $10 (base), $15 (CA), $20 (CA + auto), $25 (premium) - a premium auto lead from CA gets $25.\n\n### Pricing Service\n\nExternal APIs enable dynamic pricing based on market conditions, buyer demand, lead quality, or custom algorithms. Services return price and reason; fallback price used if service fails.\n\n### Override Pricing\n\n**Purchase Override**: Sources can specify their own price, bypassing normal purchase pricing calculation. Used for special campaigns, negotiated deals, test leads, or credits.\n\n**Sale Override**: Recipients can specify their own price, bypassing normal sale pricing calculation. Used for custom buyer agreements or special pricing arrangements.\n\n**Technical Note**: When `override: true`, the `prices` array must be empty, null, or undefined. The price will be set to whatever amount is provided by the source or recipient.\n\n## Purchase Pricing\n\nCalculated during lead submission before acceptance criteria. Can be fixed per lead seller, geographic-based, quality-based, or dynamic via external services. Recorded on source events for lead seller reconciliation and margin calculation.\n\n**Common Patterns**:\n- Fixed: $25.00 per lead\n- Geographic: $10 base, $15 for CA/NY/FL, $20 for TX \n- Quality: $5 base + premiums for TrustedForm certified leads, leads with extended data\n- Time-Based - $25 business hours, $30 weekends, $15 late night\n- Dynamic: External service with fallback pricing\n\n## Sale Pricing\n\nConfigured on recipient steps, calculated during delivery after lead acceptance. Each buyer can have different pricing for the same lead. Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Common Patterns**:\n- Fixed: $45.00 per delivered lead\n- Tiered: $30 base, $50 for high loan amounts, $75 for premium credit scores\n- Multi-buyer: $100 exclusive, $25 shared pools\n- Revenue aggregation: Multiple successful deliveries sum to total revenue\n\n## Reporting and Reconciliation\n\n**Key Metrics**: Total spend/revenue by lead seller/buyer, cost/revenue per lead, margin analysis, ROI by lead type.\n\n**Monthly Reconciliation**: \n- Lead seller payments: Sum purchase_price from source events\n- Buyer invoicing: Sum sale_price from successful recipient events\n\n**Revenue from Success**: Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Return Feedback Credits**: Handle quality issues through return feedback mechanism with negative pricing entries for reconciliation.\n\n**Dispute Resolution**: Every event contains pricing configuration, evaluated data, and rule matches for complete audit trail.","type":"object","properties":{"override":{"description":"Allows a source or a recipient to specify the price rather than\nrelying on `prices`\n","type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.override","typeLabel":"boolean"},"prices":{"description":"The list of prices to evaluate for each lead","type":"array","items":{"description":"A price determines the `purchase_price` or `sale_price` for a lead. If\nall rules in the `rule_set` pass, then the appropriate price property\nwill be set equal to the `amount`. When more than one price is\nspecified, the last matching price will be used to set the price\nproperty on the event.\n","type":"object","properties":{"amount":{"description":"The price of the lead in USD","type":"number","exclusiveMinimum":0,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].amount","typeLabel":"number"},"id":{"$circularRef":"5d3151ea-7285-4faa-9e58-f06d41c57a09","description":"ID of this price (matches the ID of the corresponding price configuration)\n","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].id","typeLabel":"any"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The rule set which must pass in order for this price to be\nconsidered\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"required":["amount"],"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices.items.[INDEX]","typeLabel":"object"},"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing.prices","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].pricing","typeLabel":"object"},"enabled":{"type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].enabled","typeLabel":"boolean"},"retry_enabled":{"type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].retry_enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX].metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"required":["type","entity","integration"],"uniqueKey":"steps.items.[INDEX].oneOf.3.steps.items.[INDEX]","typeLabel":"Recipient Step · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.steps","typeLabel":"Recipient Step · object[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.id","typeLabel":"string"},"description":{"type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.3.description","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"A rule set is a collection of rules to evaluate. The `op` property determines whether all rules must pass (`and`) or just one of them must pass (`or`) in order for the rule set to be considered passing.\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.rule_set","typeLabel":"Rule Set · object"},"pricing":{"description":"Pricing in LeadConduit automates your financial operations by calculating purchase costs (what you pay lead sellers) and sale prices (what you charge buyers) for every lead. It automates pricing based on dynamic criteria you define, typically reflecting what's in your business agreements.\n\nPricing configurations are primarily an array of prices that can be set to fixed amounts, calculated based on conditional rules, or provided by your own pricing service for each lead. Pricing can be set at the flow, flow source, and recipient step level. \n\nPricing determines the `purchase_price` and `sale_price` properties on events, and consequently the `cost` and `revenue` properties. These properties are available via the statistics API and reporting API. If no pricing is configured, these properties default to `0`. Price is recorded on the lead event, creating a complete audit trail for reconciliation, lead seller payments, and buyer invoicing.\n\n## How Pricing Works\n\n### Two Types of Pricing\n\n**Purchase Pricing**: What you pay lead sellers for leads. Calculated during submission, recorded on source events. Can be fixed per lead seller, dynamic based on lead characteristics, determined by external services, or overridden by sources.\n\n**Sale Pricing**: What you charge buyers for leads. Calculated during delivery, recorded on recipient events. Each buyer can have different pricing for the same lead.\n\n### Purchase Pricing Evaluation Layers\n\nFor purchase pricing, three layers with precedence order (first match wins):\n\n1. **Pricing Service**: Contact an external API for real-time/dynamic pricing with fallback\n2. **Source Pricing Rules**: Source-specific rules that override flow-level pricing \n3. **Flow Pricing Rules**: Base pricing rules when no other pricing applies\n\n### Pricing Rules\n\nPricing rules use LeadConduit's rule engine with **last matching price wins** behavior. This allows general-to-specific pricing where more specific conditions override general ones.\n\n**Limits**: Max $1,000,000, default $0.00, negative prices only via return feedback credits.\n\n**Example**: For prices $10 (base), $15 (CA), $20 (CA + auto), $25 (premium) - a premium auto lead from CA gets $25.\n\n### Pricing Service\n\nExternal APIs enable dynamic pricing based on market conditions, buyer demand, lead quality, or custom algorithms. Services return price and reason; fallback price used if service fails.\n\n### Override Pricing\n\n**Purchase Override**: Sources can specify their own price, bypassing normal purchase pricing calculation. Used for special campaigns, negotiated deals, test leads, or credits.\n\n**Sale Override**: Recipients can specify their own price, bypassing normal sale pricing calculation. Used for custom buyer agreements or special pricing arrangements.\n\n**Technical Note**: When `override: true`, the `prices` array must be empty, null, or undefined. The price will be set to whatever amount is provided by the source or recipient.\n\n## Purchase Pricing\n\nCalculated during lead submission before acceptance criteria. Can be fixed per lead seller, geographic-based, quality-based, or dynamic via external services. Recorded on source events for lead seller reconciliation and margin calculation.\n\n**Common Patterns**:\n- Fixed: $25.00 per lead\n- Geographic: $10 base, $15 for CA/NY/FL, $20 for TX \n- Quality: $5 base + premiums for TrustedForm certified leads, leads with extended data\n- Time-Based - $25 business hours, $30 weekends, $15 late night\n- Dynamic: External service with fallback pricing\n\n## Sale Pricing\n\nConfigured on recipient steps, calculated during delivery after lead acceptance. Each buyer can have different pricing for the same lead. Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Common Patterns**:\n- Fixed: $45.00 per delivered lead\n- Tiered: $30 base, $50 for high loan amounts, $75 for premium credit scores\n- Multi-buyer: $100 exclusive, $25 shared pools\n- Revenue aggregation: Multiple successful deliveries sum to total revenue\n\n## Reporting and Reconciliation\n\n**Key Metrics**: Total spend/revenue by lead seller/buyer, cost/revenue per lead, margin analysis, ROI by lead type.\n\n**Monthly Reconciliation**: \n- Lead seller payments: Sum purchase_price from source events\n- Buyer invoicing: Sum sale_price from successful recipient events\n\n**Revenue from Success**: Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Return Feedback Credits**: Handle quality issues through return feedback mechanism with negative pricing entries for reconciliation.\n\n**Dispute Resolution**: Every event contains pricing configuration, evaluated data, and rule matches for complete audit trail.","type":"object","properties":{"override":{"description":"Allows a source or a recipient to specify the price rather than\nrelying on `prices`\n","type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.override","typeLabel":"boolean"},"prices":{"description":"The list of prices to evaluate for each lead","type":"array","items":{"description":"A price determines the `purchase_price` or `sale_price` for a lead. If\nall rules in the `rule_set` pass, then the appropriate price property\nwill be set equal to the `amount`. When more than one price is\nspecified, the last matching price will be used to set the price\nproperty on the event.\n","type":"object","properties":{"amount":{"description":"The price of the lead in USD","type":"number","exclusiveMinimum":0,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].amount","typeLabel":"number"},"id":{"$circularRef":"5d3151ea-7285-4faa-9e58-f06d41c57a09","description":"ID of this price (matches the ID of the corresponding price configuration)\n","uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].id","typeLabel":"any"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The rule set which must pass in order for this price to be\nconsidered\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"required":["amount"],"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices.items.[INDEX]","typeLabel":"object"},"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing.prices","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.pricing","typeLabel":"object"},"enabled":{"type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.3.enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.3.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.3","typeLabel":"Distribution Step · object"},{"type":"object","title":"Parallel Step","description":"Not available yet: saving a flow with a parallel step returns 422. A parallel step is a\ncontainer for recipient and filter steps that run at the same time instead of in order.\n","required":["type","steps"],"x-internal":true,"properties":{"type":{"type":"string","enum":["parallel"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.type","typeLabel":"enum\u003cstring>"},"steps":{"type":"array","minItems":1,"items":{"oneOf":[{"type":"object","title":"Recipient Step","description":"A recipient step is used to send leads out of LeadConduit. It is used to connect with add-on services or to \ninvoke any outbound integration.\n","required":["type","entity","integration"],"properties":{"type":{"type":"string","enum":["recipient"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.type","typeLabel":"enum\u003cstring>"},"entity":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier for an entity","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.entity.id","typeLabel":"string"},"name":{"type":"string","readOnly":true,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.entity.name","typeLabel":"string"},"time_zone":{"type":"string","example":"America/New_York","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.entity.time_zone","typeLabel":"string"}},"additionalProperties":false,"required":["id","name"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.entity","typeLabel":"object"},"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.integration","typeLabel":"object"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.id","typeLabel":"string"},"description":{"type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.description","typeLabel":"string"},"notes":{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.notes","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"A rule set is a collection of rules to evaluate. The `op` property determines whether all rules must pass (`and`) or just one of them must pass (`or`) in order for the rule set to be considered passing.\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.rule_set","typeLabel":"Rule Set · object"},"feedback":{"description":"Feedback specifies the configuration for receiving and sending feedback\nabout a lead. When receiving feedback from a recipient, the `rule_set`\nmust pass. If it does not, a \"failure\" Feedback Received Event is\ncreated. When sending feedback to a source, the `rule_set` must pass. If\nit does not, a \" skip\" Feedback Sent Event is created.\n","properties":{"integration":{"type":"object","properties":{"module_id":{"title":"Integration Module ID","type":"string","description":"A pointer to the integration code to use for this integration\n","example":"leadconduit-salesforce.outbound.create_contact","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.module_id","typeLabel":"string"},"mappings":{"oneOf":[{"type":"array","items":{"description":"Mappings transform data between systems using rule-based translations. They handle field renaming, data restructuring, and conditional transformations for both inbound (sources) and outbound (recipients) data.\n\n## Core Structure\n\nEach mapping has three components:\n1. **Property**: Destination field name\n2. **Value**: Template-based value assignment\n3. **Rule Set**: Optional conditions for application\n\n```json\n{\n \"property\": \"full_name\",\n \"value\": \"{{lead.first_name}} {{lead.last_name}}\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [{\"lhv\": \"lead.state\", \"op\": \"is equal to\", \"rhv\": \"TX\"}]\n }\n}\n```\n\n## Inbound vs Outbound Mapping\n\n### Inbound Mapping (Source → LeadConduit)\n**Purpose**: Standardize field names during lead submission\n**Context**: Raw submission data before the lead object exists\n**Use Case**: Only needed when source field names don't match LeadConduit standards\n\n**Technical Detail**: Inbound mappings execute in the handler before the lead object is created. Templates can only reference raw submission fields (not `lead.field` syntax). The `lead.` prefix in properties tells the system to assign values to the lead object that will be created after mapping.\n\n```json\n// Source sends non-standard names\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_addr}}\"}\n]\n```\n\n**Key Rules**:\n- Use exact source field names in value templates (no `lead.` prefix)\n- Use LeadConduit field IDs in property templates (with `lead.` prefix)\n- Don't transform data - let type system handle normalization\n- Field renaming only\n\n### Outbound Mapping (LeadConduit → Recipient)\n**Purpose**: Transform processed data for recipient requirements\n**Context**: Complete lead data with all type components, all appended data\n**Use Case**: Format data, combine fields, extract components\n\n```json\n[\n {\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"},\n {\"property\": \"FormattedPhone\", \"value\": \"({{lead.phone_1.area}}) {{lead.phone_1.exchange}}-{{lead.phone_1.line}}\"},\n {\"property\": \"EmailDomain\", \"value\": \"{{lead.email.domain}}\"}\n]\n```\n\n**Key Rules**:\n- Use LeadConduit field IDs in templates\n- Leverage field value's components provided by the field's type\n- Transform data for recipient needs\n- Use conditional logic for business rules\n\n## Property Path Syntax\n\n**Simple**: `\"email\"`\n**Nested**: `\"contact.primary.email\"` → `{contact: {primary: {email: \"value\"}}}`\n**Arrays**: `\"phones.0\"` → `{phones: [\"value\"]}`\n**Special Keys**: `\"data{2024}.revenue\"` → `{data: {\"2024\": {revenue: \"value\"}}}`\n\n## Template Features\n\n**Field Access**: `{{lead.email}}`\n**Components**: `{{lead.phone_1.area}}`\n**Formatting**: `{{format lead.dob format=\"MM/DD/YYYY\"}}`\n**Calculations**: `{{math lead.loan_amount * 1.05}}`\n**Combinations**: `{{lead.first_name}} {{lead.last_name}}`\n\n## Common Patterns\n\n**Basic Field Renaming (Inbound)**:\n```json\n[\n {\"property\": \"lead.first_name\", \"value\": \"{{fname}}\"},\n {\"property\": \"lead.email\", \"value\": \"{{email_address}}\"}\n]\n```\n\n**Field Combining (Outbound)**:\n```json\n{\"property\": \"FullName\", \"value\": \"{{lead.first_name}} {{lead.last_name}}\"}\n```\n\n**Conditional Fields**:\n```json\n{\n \"property\": \"premium_lead\",\n \"value\": \"true\",\n \"rule_set\": {\n \"op\": \"and\",\n \"rules\": [\n {\"lhv\": \"lead.annual_income\", \"op\": \"is greater than\", \"rhv\": \"100000\"}\n ]\n }\n}\n```\n\n**Static Field Value**:\n```json\n{\n \"property\": \"aff_id\",\n \"value\": \"aff-103331\",\n}\n```\n\n**Nested Structures**:\n```json\n[\n {\"property\": \"applicant.name.first\", \"value\": \"{{lead.first_name}}\"},\n {\"property\": \"applicant.contact.email\", \"value\": \"{{lead.email}}\"}\n]\n```\n\n**Conditional Field Value Based on Precedence**:\n```json\n[\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_2}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_2.valid\", \"op\": \"is true\"}]}\n },\n {\n \"property\": \"best_phone\",\n \"value\": \"{{lead.phone_1}}\",\n \"rule_set\": {\"rules\": [{\"lhv\": \"lead.phone_1.valid\", \"op\": \"is true\"}]}\n }\n]\n```\n\n## Special Behaviors\n\n**Processing Order**: Mappings apply sequentially, allowing overwrites\n**Empty Values**: Template results that are empty are skipped; explicit empty strings are applied\n**Type Preservation**: Simple variable templates preserve data types; string concatenation converts to string\n**Error Recovery**: Individual mapping failures don't stop processing\n\n## Best Practices\n\n**Inbound**: Only map fields with different names; let type system handle normalization; use simple templates\n**Outbound**: Use type components instead of string parsing; make property names self-documenting; test edge cases\n**Performance**: Order rules efficiently; minimize complex templates; group related mappings\n\n## Common Pitfalls\n\n### Pitfall: Transforming on Inbound\n❌ **Wrong**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{lowercase email_address}}\" // Don't do this!\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"lead.email\",\n \"value\": \"{{email_address}}\" // Type system handles lowercasing\n}\n```\n\n### Pitfall: Using Wrong Field Names\n❌ **Wrong**:\n```json\n// In outbound mapping:\n{\n \"value\": \"{{lead.phone_1.area}}\" // Backend syntax\n}\n```\n✅ **Right**:\n```json\n{\n \"value\": \"{{Phone 1 > Area}}\" // UI display name with component\n}\n```\n\n### Pitfall: Over-Mapping\n❌ **Wrong**: Mapping fields that already match\n```json\n// If source sends \"email\", don't do this:\n{ \"property\": \"lead.email\", \"value\": \"{{email}}\" } // Unnecessary!\n```\n✅ **Right**: Only map when names differ\n\n### Pitfall: String Manipulation Instead of Components\n❌ **Wrong**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{substring Phone 1 start=1 end=4}}\"\n}\n```\n✅ **Right**:\n```json\n{\n \"property\": \"area_code\",\n \"value\": \"{{Phone 1 > Area}}\"\n}\n```\n\n## Integration\n\n**With Types**: Inbound mappings happen before type conversion, outbound after\n**With Rules**: Control when mappings apply based on business logic\n**With Templates**: Provide dynamic values from lead data and components","type":"object","properties":{"property":{"description":"The name of the variable to set","type":"string","minLength":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].property","typeLabel":"string"},"value":{"oneOf":[{"type":"string","title":"Template","description":"The value to set","x-tags":["Templates"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.0","typeLabel":"string"},{"type":"number","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.1","typeLabel":"number"},{"type":"null","description":"The value to set","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.2","typeLabel":"null"},{"type":"array","items":{"oneOf":[{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX].oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3.items.[INDEX]","typeLabel":"string | null"},"description":"The value to set","minItems":1,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value.oneOf.3","typeLabel":"(string | null)[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].value","typeLabel":"string | number | null | (string | null)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this mapping","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].id","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"Only apply the mapping if this rule set passes","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["property","value"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0.items.[INDEX]","typeLabel":"object"},"description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.0","typeLabel":"object[]"},{"type":"null","description":"The mappings to apply to lead data when interacting with this\nintegration\n","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration.mappings","typeLabel":"object[] | null"}},"additionalProperties":false,"required":["module_id"],"description":"The integration to be used for the feedback","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.integration","typeLabel":"object"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"If the rules fail the feedback is not performed","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback.rule_set","typeLabel":"Rule Set · object"}},"additionalProperties":false,"required":["integration"],"type":"object","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.feedback","typeLabel":"object"},"caps":{"oneOf":[{"type":"null","description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.0","typeLabel":"null"},{"type":"array","items":{"x-tags":["Caps and Limits"],"type":"object","description":"A cap allows limiting the number of leads sent into or out of a flow. \nIf a lead is successful, it will be counted against the maximum configured leads. \nIf configured, the rule set will be evaluated to determine whether a lead will be counted against the cap.\n","properties":{"id":{"type":"string","description":"The unique identifier of the cap","pattern":"^[0-9a-fA-F]{24}$","example":"5fd438f91f0d12766e2bfee5","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].id","typeLabel":"string"},"type":{"type":"string","description":"The type of this cap (LeadConduit may eventually support different types of caps)","enum":["volume"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"name":{"description":"The human-readable name of the cap","type":"string","example":"Monthly leads from TX","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"number","description":"The number of successful leads that will be accepted","example":1200,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].maximum","typeLabel":"number"},"duration":{"type":"number","description":"The number duration_units for which the cap persists","minimum":1,"examples":[1],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].duration","typeLabel":"number"},"duration_units":{"type":"string","description":"The unit of time for which the cap persists","enum":["month","week","day","hour","minute"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].duration_units","typeLabel":"enum\u003cstring>"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for the lead to count against the cap","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].rule_set","typeLabel":"Rule Set · object"},"caps":{"description":"Nested caps evaluated if rules for the parent cap pass","type":"array","items":{"$circularRef":"a0504bde-eae4-48cd-8488-ce131a7ae199"},"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].caps","typeLabel":"array"},"time_zone":{"description":"The time zone in which cap resets","type":"string","example":"America/New_York","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].time_zone","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the cap is met this is the reason (default: 'Cap reached')","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].reason","typeLabel":"string"},"created_at":{"description":"Read-only time the cap was created","type":"string","format":"date-time","example":"2020-11-23T11:41:52Z","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1.items.[INDEX]","typeLabel":"object"},"description":"A cap controls the behavior by setting the maximum and the duration. The counter for a cap is kept as a standalone record which shares cap's ID.\n","minItems":1,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps.oneOf.1","typeLabel":"object[]"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.caps","typeLabel":"null | object[]"},"pricing":{"description":"Pricing in LeadConduit automates your financial operations by calculating purchase costs (what you pay lead sellers) and sale prices (what you charge buyers) for every lead. It automates pricing based on dynamic criteria you define, typically reflecting what's in your business agreements.\n\nPricing configurations are primarily an array of prices that can be set to fixed amounts, calculated based on conditional rules, or provided by your own pricing service for each lead. Pricing can be set at the flow, flow source, and recipient step level. \n\nPricing determines the `purchase_price` and `sale_price` properties on events, and consequently the `cost` and `revenue` properties. These properties are available via the statistics API and reporting API. If no pricing is configured, these properties default to `0`. Price is recorded on the lead event, creating a complete audit trail for reconciliation, lead seller payments, and buyer invoicing.\n\n## How Pricing Works\n\n### Two Types of Pricing\n\n**Purchase Pricing**: What you pay lead sellers for leads. Calculated during submission, recorded on source events. Can be fixed per lead seller, dynamic based on lead characteristics, determined by external services, or overridden by sources.\n\n**Sale Pricing**: What you charge buyers for leads. Calculated during delivery, recorded on recipient events. Each buyer can have different pricing for the same lead.\n\n### Purchase Pricing Evaluation Layers\n\nFor purchase pricing, three layers with precedence order (first match wins):\n\n1. **Pricing Service**: Contact an external API for real-time/dynamic pricing with fallback\n2. **Source Pricing Rules**: Source-specific rules that override flow-level pricing \n3. **Flow Pricing Rules**: Base pricing rules when no other pricing applies\n\n### Pricing Rules\n\nPricing rules use LeadConduit's rule engine with **last matching price wins** behavior. This allows general-to-specific pricing where more specific conditions override general ones.\n\n**Limits**: Max $1,000,000, default $0.00, negative prices only via return feedback credits.\n\n**Example**: For prices $10 (base), $15 (CA), $20 (CA + auto), $25 (premium) - a premium auto lead from CA gets $25.\n\n### Pricing Service\n\nExternal APIs enable dynamic pricing based on market conditions, buyer demand, lead quality, or custom algorithms. Services return price and reason; fallback price used if service fails.\n\n### Override Pricing\n\n**Purchase Override**: Sources can specify their own price, bypassing normal purchase pricing calculation. Used for special campaigns, negotiated deals, test leads, or credits.\n\n**Sale Override**: Recipients can specify their own price, bypassing normal sale pricing calculation. Used for custom buyer agreements or special pricing arrangements.\n\n**Technical Note**: When `override: true`, the `prices` array must be empty, null, or undefined. The price will be set to whatever amount is provided by the source or recipient.\n\n## Purchase Pricing\n\nCalculated during lead submission before acceptance criteria. Can be fixed per lead seller, geographic-based, quality-based, or dynamic via external services. Recorded on source events for lead seller reconciliation and margin calculation.\n\n**Common Patterns**:\n- Fixed: $25.00 per lead\n- Geographic: $10 base, $15 for CA/NY/FL, $20 for TX \n- Quality: $5 base + premiums for TrustedForm certified leads, leads with extended data\n- Time-Based - $25 business hours, $30 weekends, $15 late night\n- Dynamic: External service with fallback pricing\n\n## Sale Pricing\n\nConfigured on recipient steps, calculated during delivery after lead acceptance. Each buyer can have different pricing for the same lead. Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Common Patterns**:\n- Fixed: $45.00 per delivered lead\n- Tiered: $30 base, $50 for high loan amounts, $75 for premium credit scores\n- Multi-buyer: $100 exclusive, $25 shared pools\n- Revenue aggregation: Multiple successful deliveries sum to total revenue\n\n## Reporting and Reconciliation\n\n**Key Metrics**: Total spend/revenue by lead seller/buyer, cost/revenue per lead, margin analysis, ROI by lead type.\n\n**Monthly Reconciliation**: \n- Lead seller payments: Sum purchase_price from source events\n- Buyer invoicing: Sum sale_price from successful recipient events\n\n**Revenue from Success**: Only successful deliveries generate revenue; failed deliveries don't count.\n\n**Return Feedback Credits**: Handle quality issues through return feedback mechanism with negative pricing entries for reconciliation.\n\n**Dispute Resolution**: Every event contains pricing configuration, evaluated data, and rule matches for complete audit trail.","type":"object","properties":{"override":{"description":"Allows a source or a recipient to specify the price rather than\nrelying on `prices`\n","type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.override","typeLabel":"boolean"},"prices":{"description":"The list of prices to evaluate for each lead","type":"array","items":{"description":"A price determines the `purchase_price` or `sale_price` for a lead. If\nall rules in the `rule_set` pass, then the appropriate price property\nwill be set equal to the `amount`. When more than one price is\nspecified, the last matching price will be used to set the price\nproperty on the event.\n","type":"object","properties":{"amount":{"description":"The price of the lead in USD","type":"number","exclusiveMinimum":0,"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].amount","typeLabel":"number"},"id":{"$circularRef":"5d3151ea-7285-4faa-9e58-f06d41c57a09","description":"ID of this price (matches the ID of the corresponding price configuration)\n","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].id","typeLabel":"any"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The rule set which must pass in order for this price to be\nconsidered\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"required":["amount"],"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices.items.[INDEX]","typeLabel":"object"},"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing.prices","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.pricing","typeLabel":"object"},"enabled":{"type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.enabled","typeLabel":"boolean"},"retry_enabled":{"type":"boolean","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.retry_enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.0","typeLabel":"Recipient Step · object"},{"type":"object","title":"Filter Step","description":"A filter step is used to stop processing a lead from advancing to the\nnext flow step. This is conceptually similar to an email inbox filter.\nIf the lead matches the rules then the flow is stopped, which\neffectively filters out the lead. When a filter step stops the flow, the\nsource receives an immediate response and no further steps are\nprocessed.\n","required":["type","outcome","rule_set"],"properties":{"type":{"description":"The type of the step (always `filter`)","type":"string","enum":["filter"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.type","typeLabel":"enum\u003cstring>"},"outcome":{"description":"When the flow stops, `success`, `failure` or `error` is returned to\nthe source that submitted the lead\n","type":"string","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.outcome","typeLabel":"string"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The flow stops when the rules match the lead","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.rule_set","typeLabel":"Rule Set · object"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this step","uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.id","typeLabel":"string"},"description":{"description":"A brief description of what this filter does","type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.description","typeLabel":"string"},"notes":{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.notes","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the outcome is `failure` or `error`, this is the reason to\nprovide to the source\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.reason","typeLabel":"string"},"enabled":{"description":"Whether this step should be run when processing a lead or not\n","type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.enabled","typeLabel":"boolean"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX].oneOf.1","typeLabel":"Filter Step · object"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.steps.items.[INDEX]","typeLabel":"Recipient Step · object | Filter Step · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.steps","typeLabel":"(Recipient Step · object | Filter Step · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.id","typeLabel":"string"},"description":{"oneOf":[{"type":"string","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.4.description.oneOf.0","typeLabel":"string"},{"type":"null","maxLength":120,"uniqueKey":"steps.items.[INDEX].oneOf.4.description.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.description","typeLabel":"string | null"},"notes":{"oneOf":[{"type":"string","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.4.notes.oneOf.0","typeLabel":"string"},{"type":"null","maxLength":2000,"uniqueKey":"steps.items.[INDEX].oneOf.4.notes.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.notes","typeLabel":"string | null"},"enabled":{"type":"boolean","default":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.enabled","typeLabel":"boolean"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"A rule set is a collection of rules to evaluate. The `op` property determines whether all rules must pass (`and`) or just one of them must pass (`or`) in order for the rule set to be considered passing.\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"steps.items.[INDEX].oneOf.4.rule_set","typeLabel":"Rule Set · object"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"steps.items.[INDEX].oneOf.4.metadata","typeLabel":"Metadata · object | null"},"timeout_ms":{"description":"How long the contained steps may run, in milliseconds","type":"integer","exclusiveMinimum":0,"maximum":359999,"uniqueKey":"steps.items.[INDEX].oneOf.4.timeout_ms","typeLabel":"integer"},"on_timeout":{"description":"What happens to the lead when the contained steps run past `timeout_ms`","type":"string","enum":["error","skip"],"uniqueKey":"steps.items.[INDEX].oneOf.4.on_timeout","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"steps.items.[INDEX].oneOf.4","typeLabel":"Parallel Step · object"}],"uniqueKey":"steps.items.[INDEX]","typeLabel":"Calculated Step · object | Filter Step · object | Recipient Step · object | Distribution Step · object | Parallel Step · object"},"isRequired":true,"uniqueKey":"steps","typeLabel":"(Calculated Step · object | Filter Step · object | Recipient Step · object | Distribution Step · object | Parallel Step · object)[]"},"id":{"type":"string","description":"The unique identifier for a flow","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","uniqueKey":"id","typeLabel":"string"},"errors":{"type":"object","description":"Errors preventing this flow from being saved","readOnly":true,"uniqueKey":"errors","typeLabel":"object"},"caps":{"oneOf":[{"type":"null","description":"Caps on leads submitted into this flow from any source. These caps will be processed before caps set on a source.","uniqueKey":"caps.oneOf.0","typeLabel":"null"},{"type":"array","items":{"x-tags":["Caps and Limits"],"type":"object","description":"A cap allows limiting the number of leads sent into or out of a flow. \nIf a lead is successful, it will be counted against the maximum configured leads. \nIf configured, the rule set will be evaluated to determine whether a lead will be counted against the cap.\n","properties":{"id":{"type":"string","description":"The unique identifier of the cap","pattern":"^[0-9a-fA-F]{24}$","example":"5fd438f91f0d12766e2bfee5","uniqueKey":"caps.oneOf.1.items.[INDEX].id","typeLabel":"string"},"type":{"type":"string","description":"The type of this cap (LeadConduit may eventually support different types of caps)","enum":["volume"],"uniqueKey":"caps.oneOf.1.items.[INDEX].type","typeLabel":"enum\u003cstring>"},"name":{"description":"The human-readable name of the cap","type":"string","example":"Monthly leads from TX","uniqueKey":"caps.oneOf.1.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"number","description":"The number of successful leads that will be accepted","example":1200,"uniqueKey":"caps.oneOf.1.items.[INDEX].maximum","typeLabel":"number"},"duration":{"type":"number","description":"The number duration_units for which the cap persists","minimum":1,"examples":[1],"uniqueKey":"caps.oneOf.1.items.[INDEX].duration","typeLabel":"number"},"duration_units":{"type":"string","description":"The unit of time for which the cap persists","enum":["month","week","day","hour","minute"],"uniqueKey":"caps.oneOf.1.items.[INDEX].duration_units","typeLabel":"enum\u003cstring>"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for the lead to count against the cap","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"caps.oneOf.1.items.[INDEX].rule_set","typeLabel":"Rule Set · object"},"caps":{"description":"Nested caps evaluated if rules for the parent cap pass","type":"array","items":{"$circularRef":"a0504bde-eae4-48cd-8488-ce131a7ae199"},"uniqueKey":"caps.oneOf.1.items.[INDEX].caps","typeLabel":"array"},"time_zone":{"description":"The time zone in which cap resets","type":"string","example":"America/New_York","uniqueKey":"caps.oneOf.1.items.[INDEX].time_zone","typeLabel":"string"},"reason":{"type":"string","title":"Template","description":"When the cap is met this is the reason (default: 'Cap reached')","x-tags":["Templates"],"uniqueKey":"caps.oneOf.1.items.[INDEX].reason","typeLabel":"string"},"created_at":{"description":"Read-only time the cap was created","type":"string","format":"date-time","example":"2020-11-23T11:41:52Z","uniqueKey":"caps.oneOf.1.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"caps.oneOf.1.items.[INDEX]","typeLabel":"object"},"description":"Caps on leads submitted into this flow from any source. These caps will be processed before caps set on a source.","minItems":1,"uniqueKey":"caps.oneOf.1","typeLabel":"object[]"}],"uniqueKey":"caps","typeLabel":"null | object[]"},"acceptance_criteria":{"title":"Acceptance Criteria","type":"object","properties":{"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"This rule set must pass in order for a lead to be accepted","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"acceptance_criteria.rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"acceptance_criteria.rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"acceptance_criteria.rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"isRequired":true,"uniqueKey":"acceptance_criteria.rule_set","typeLabel":"Rule Set · object"},"outcome":{"type":"string","description":"When the rule set fails, `success`, `failure` or `error` is returned to the source that submitted the lead","enum":["success","failure","error"],"example":"failure","isRequired":true,"uniqueKey":"acceptance_criteria.outcome","typeLabel":"enum\u003cstring>"},"reason":{"type":"string","title":"Template","description":"When the outcome is `failure`, this is the reason to provide to the source","x-tags":["Templates"],"example":"Lead must live in TX","uniqueKey":"acceptance_criteria.reason","typeLabel":"string"}},"additionalProperties":false,"required":["outcome","rule_set"],"description":"A submitted lead that fails an acceptance criteria rule will be rejected. Lead submission will result in a failure outcome.","uniqueKey":"acceptance_criteria","typeLabel":"Acceptance Criteria · object"},"pricing":{"description":"This pricing configuration applies to all leads submitted to this flow. Pricing determines the value of \nthe `purchase_price` and `cost` property on the source event recorded when a lead is submitted. \n\nEach price is evaluated and the last price for which all rules match will determine the amount used\nfor the `purchase_price` and `cost`. If none of these prices match for a particular lead, source pricing\nwill be evaluated. If no price matches, the price properties on the source event will be set to `0`.\n","type":"object","properties":{"override":{"description":"Allows a source or a recipient to specify the price rather than\nrelying on `prices`\n","type":"boolean","uniqueKey":"pricing.override","typeLabel":"boolean"},"prices":{"description":"The list of prices to evaluate for each lead","type":"array","items":{"description":"A price determines the `purchase_price` or `sale_price` for a lead. If\nall rules in the `rule_set` pass, then the appropriate price property\nwill be set equal to the `amount`. When more than one price is\nspecified, the last matching price will be used to set the price\nproperty on the event.\n","type":"object","properties":{"amount":{"description":"The price of the lead in USD","type":"number","exclusiveMinimum":0,"isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].amount","typeLabel":"number"},"id":{"$circularRef":"5d3151ea-7285-4faa-9e58-f06d41c57a09","description":"ID of this price (matches the ID of the corresponding price configuration)\n","uniqueKey":"pricing.prices.items.[INDEX].id","typeLabel":"any"},"rule_set":{"x-tags":["Rules"],"title":"Rule Set","type":"object","description":"The rule set which must pass in order for this price to be\nconsidered\n","properties":{"op":{"type":"string","description":"Determines whether all rules or just some rules must pass for the overall set to pass","enum":["and","or"],"x-enumDescriptions":{"and":"All rules in the set must pass","or":"Only one rule in the set must pass"},"isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.op","typeLabel":"enum\u003cstring>"},"rules":{"type":"array","description":"The required rules to be evaluated. Rule sets may also be specified as array elements in order to achieve nesting.","minItems":1,"items":{"oneOf":[{"type":"object","title":"Binary Rule","required":["lhv","op","rhv"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The required left-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.state","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is equal to","is not equal to","is less than","is less than or equal to","is greater than","is greater than or equal to","is included in","is not included in","includes","does not include","is between","is not between","matches pattern","does not match pattern"],"example":"is equal to","x-enumDescriptions":{"is equal to":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type) (case-insensitive), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` equal to the `rhv`?","is not equal to":"Inverse of the `is equal to` operator.","is less than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than the `rhv`?","is less than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically less than or equal to the `rhv`?","is greater than":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than the `rhv`?","is greater than or equal to":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` numerically more than or equal to the `rhv`?","is between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` between the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (inclusive)?","is not between":"Is the [numeric](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type) or [range average](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `lhv` outside the `rhv` [range](https://developers.activeprospect.com/api-reference/leadconduit/types#range-type) `min` and `max` (exclusive)?","is included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` included in the Array of values provided in the `rhv`?","is not included in":"Is the [string](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [number](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [boolean](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) `lhv` missing from the Array of values provided in the `rhv`?","includes":"Does the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` contain the `rhv`?","does not include":"Is the Array of [strings](https://developers.activeprospect.com/api-reference/leadconduit/types#string-type), [numbers](https://developers.activeprospect.com/api-reference/leadconduit/types#number-type), or [booleans](https://developers.activeprospect.com/api-reference/leadconduit/types#boolean-type) provided in the `lhv` missing the `rhv`?"},"description":"Binary operators compare the `lhv` and the `rhv`.\n","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.op","typeLabel":"enum\u003cstring>"},"rhv":{"oneOf":[{"type":"string","title":"Template","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"TX","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.0","typeLabel":"string"},{"type":"number","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.1","typeLabel":"number"},{"type":"boolean","description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.2","typeLabel":"boolean"},{"type":"array","items":{"type":"string","title":"Template","description":"# LeadConduit Templates\n\n## Overview\n\nTemplates are the dynamic value engine of LeadConduit. They transform static configurations into intelligent, adaptive systems by resolving variables, computing values, and manipulating data at runtime. Think of templates as smart placeholders that know how to fetch and transform data when needed.\n\nTemplates answer a fundamental question:\n**How do I get the right value at the right time?**\n\nTemplates work seamlessly with rules and mappings:\n- **Rules** use templates for dynamic comparisons\n- **Mappings** use templates to compute values\n- **Templates** provide the bridge between configuration and runtime data\n\n## Why Templates Exist\n\n### The Static Configuration Problem\nWithout templates, every value would be hard-coded:\n- Phone format: \"(512) 789-1111\" for everyone\n- Greeting: \"Hello Customer\" instead of personalized\n- Dates: Fixed instead of calculated\n- Prices: Static instead of computed\n\nTemplates make configurations come alive with actual data.\n\n### The Data Access Problem\nLead data has complex structures:\n- Nested objects: `address_1`, `city`\n- Array elements: `tags[0]`\n- Type components: `phone.area`\n- Calculated values: `price * tax_rate`\n\nTemplates provide a consistent way to access any data, anywhere.\n\n### The Transformation Problem\nRaw data rarely matches what you need:\n- Dates need formatting\n- Names need case changes\n- Numbers need calculations\n- Strings need manipulation\n\nTemplates include helpers that transform data on the fly.\n\n### Technical Details\n\nLeadConduit supports combining, [formatting](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-formatting),\n[hashing](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-hashing), and [performing math](https://developers.activeprospect.com/api-reference/leadconduit/templates#variable-math) on\nvalues using template markup. Templating in LeadConduit is based on the\npopular [Handlebars](https://handlebarsjs.com/) semantic templating\nlibrary. A template is a string which contains any number of variable\nplaceholders\n\n## Template Variable\n\nVariable placeholders in templates start and end with two curly-brace\ncharacters: `{{ lead.first_name }}`. Multiple placeholders can be\ncombined in a single template: `{{ lead.first_name }} {{ lead.last_name\n}}`. The [universe of possible variables](https://developers.activeprospect.com/api-reference/leadconduit/variables) available to a\ntemplate depends on the [fields](https://developers.activeprospect.com/api-reference/leadconduit/fields/field) defined in your flow and the\nsteps you've added to your flow.\n\n## Variable Formatting\n\nLeadConduit has a built-in helper for formatting numbers and dates.\nFormatting a value is done with the `format` helper. If the value is a\ndate field, then you may use date formatting options with the helper.\nIf it's a number field, then you may use the number formatting options\nwith the helper.\n\n### Date Variable Formatting\n\nTo format a date, use the `format` helper: `{{ format lead.dob\nformat=\"YYYY-MM-DD\" }}` results in '2015-06-24'. The `format` option is\na string which defines the format of the date. This format can be any\ncombination of the below tokens. To escape characters in format\nstrings, you can wrap the characters in square brackets: `{{ format\nlead.dob format=\"[It's] MMMM Do\" }}` results in \"It's October 12th\".\n\n#### Date Format Tokens\n\n| | Token | Output |\n| -------------------------- | -------------------------- | -----------|\n| Month | `M` | 1 2 ... 11 12\n| | `Mo` | 1st 2nd ... 11th 12th\n| | `MM` | 01 02 ... 11 12\n| | `MMM` | Jan Feb ... Nov Dec\n| | `MMMM` | January February ... November December\n| Quarter | `Q` | 1 2 3 4\n| | `Qo` | 1st 2nd 3rd 4th\n| Day of Month | `D` | 1 2 ... 30 31\n| | `Do` | 1st 2nd ... 30th 31st\n| | `DD` | 01 02 ... 30 31\n| Day of Year | `DDD` | 1 2 ... 364 365\n| | `DDDo` | 1st 2nd ... 364th 365th\n| | `DDDD` | 001 002 ... 364 365\n| Day of Week | `d` | 0 1 ... 5 6\n| | `do` | 0th 1st ... 5th 6th\n| | `dd` | Su Mo ... Fr Sa\n| | `ddd` | Sun Mon ... Fri Sat\n| | `dddd` | Sunday Monday ... Friday Saturday\n| Day of Week (Locale) | `e` | 0 1 ... 5 6\n| Day of Week (ISO) | `E` | 1 2 ... 6 7\n| Week of Year | `w` | 1 2 ... 52 53\n| | `wo` | 1st 2nd ... 52nd 53rd\n| | `ww` | 01 02 ... 52 53\n| Week of Year (ISO) | `W` | 1 2 ... 52 53\n| | `Wo` | 1st 2nd ... 52nd 53rd\n| | `WW` | 01 02 ... 52 53\n| Year | `YY` | 70 71 ... 29 30\n| | `YYYY` | 1970 1971 ... 2029 2030\n| | `Y` | 1970 1971 ... 9999 +10000 +10001 Note: This complies with the ISO 8601 standard for dates past the year 9999\n| Week Year | `gg` | 70 71 ... 29 30\n| | `gggg` | 1970 1971 ... 2029 2030\n| Week Year (ISO) | `GG` | 70 71 ... 29 30\n| | `GGGG` | 1970 1971 ... 2029 2030\n| AM/PM | `A` | AM PM\n| | `a` | am pm\n| Hour | `H` | 0 1 ... 22 23\n| | `HH` | 00 01 ... 22 23\n| | `h` | 1 2 ... 11 12\n| | `hh` | 01 02 ... 11 12\n| | `k` | 1 2 ... 23 24\n| | `kk` | 01 02 ... 23 24\n| Minute | `m` | 0 1 ... 58 59\n| | `mm` | 00 01 ... 58 59\n| Second | `s` | 0 1 ... 58 59\n| | `ss` | 00 01 ... 58 59\n| Fractional Second | `S` | 0 1 ... 8 9\n| | `SS` | 00 01 ... 98 99\n| | `SSS` | 000 001 ... 998 999\n| | `SSSS ... SSSSSSSSS` | 000[0..] 001[0..] ... 998[0..] 999[0..]\n| Time Zone | `z` or `zz` | EST CST ... MST PST (requires use of the `timezone` option)\n| | `Z` | -07:00 -06:00 ... +06:00 +07:00\n| | `ZZ` | -0700 -0600 ... +0600 +0700\n| Unix Timestamp | `X` | 1360013296\n| Unix Millisecond Timestamp | `x` | 1360013296123\n\n#### Localized Date Formats\n\nBecause preferred formatting differs based on locale, there are a few\ntokens that can be used to format a moment based on its locale. There\nare upper and lower case variations on the same formats. The lowercase\nversion is intended to be the shortened version of its uppercase\ncounterpart. To change the locale, use the `locale` options: `{{\nformat date format=\"LLL\" locale=\"fr\" }}` results in \"24 june 2015 17:24\".\n\n| | Format string | Output |\n| ------------------------------------ | ------------- | ----------------|\n| Time | `LT` | 8:30 PM\n| Time with seconds | `LTS` | 8:30:25 PM\n| Month numeral, day of month, year | `L` | 09/04/1986\n| | `l` | 9/4/1986\n| Month name, day of month, year | `LL` | September 4, 1986\n| | `ll` | Sep 4, 1986\n| Month name, day of month, year, time | `LLL` | September 4, 1986 8:30 PM\n| | `lll` | Sep 4, 1986 8:30 PM\n| Month name, day of month, day of week, year, time | `LLLL` | Thursday, September 4, 1986 8:30 PM\n| | `llll` | Thu, Sep 4, 1986 8:30 PM\n\n### Number Variable Formatting\n\nTo format a number, use the `format` helper: `{{ format\nlead.mortgage.first_mortgage_balance format=\"$0,0.00\"}}` results in\n'$45,302.00'. The `format` option is a string which defines the format\nof the number. See the table of examples below:\n\n| Number | Format | String |\n| ---------- | ------------ | ----------- |\n| 10000 | `0,0.0000` | 10,000.0000\n| 10000.23 | `0,0` | 10,000\n| 10000.23 | `+0,0` | +10,000\n| -10000 | `0,0.0` | -10,000.0\n| 10000.1234 | `0.000` | 10000.123\n| 100.1234 | `00000` | 00100\n| 1000.1234 | `000000,0` | 001,000\n| 10 | `000.00` | 010.00\n| 10000.1234 | `0[.]00000` | 10000.12340\n| -10000 | `(0,0.0000)` | (10,000.0000)\n| -0.23 | `.00` | -.23\n| -0.23 | `(.00)` | (.23)\n| 0.23 | `0.00000` | 0.23000\n| 0.23 | `0.0[0000]` | 0.23\n| 1230974 | `0.0a` | 1.2m\n| 1460 | `0 a` | 1 k\n| -104000 | `0a` | -104k\n| 1 | `0o` | 1st\n| 100 | `0o` | 100th\n| 1000.234 | `$0,0.00` | $1,000.23\n| 1000.2 | `0,0[.]00 $` | 1,000.20 $\n| 1001 | `$ 0,0[.]00` | $ 1,001\n| -1000.234 | `($0,0)` | ($1,000)\n| -1000.234 | `$0.00` | -$1000.23\n| 1230974 | `($ 0.00 a)` | $ 1.23 m\n\nUse the `locale` option to format the number to a particular locale:\n`{{ format lead.mortgage.first_mortgage_balance locale=\"fr\"\nformat=\"$0,0.00\" }}` results in '€45 302.00'.\n\n### Converting Number and Boolean to String\n\nFields of type number and boolean can be converted to string using the `format` helper with the `dataType=\"String\"` option:\n\n`{{format field_name dataType=\"String\"}}`\n\nExample:\n- Input: `{{format lead.age dataType=\"String\"}}` with `lead.age` = 30\n- Output: \"30\"\n\n### Converting String to Number\n\nFields whose final result from the `format` helper is a string can be converted to a number if the `dataType=\"Number\"` option is passed and the value is a string representing a valid number.\n\nExamples:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = '78751'\n- Output: 78751 (as a number value)\n\nIf the string does not represent a valid number, the result will not be converted:\n- Input: `{{format lead.postal_code dataType=\"Number\"}}` with `lead.postal_code` = 'H3Z 2Y7'\n- Output: 'H3Z 2Y7'\n\nThis can also be used with dates if the formatting returns only numbers, such as epoch time:\n- Input: `{{format lead.source_timestamp format=\"X\" dataType=\"Number\"}}` with `lead.source_timestamp` = '2015-06-24T17:24:49.060Z'\n- Output: 1435166689 (as a number value)\n\n\n## Variable String Manipulation\n\nStrings can be manipulated with the following helpers:\n\n### Lowercase\n\nTransforms the value to lowercase:\n\n`{{lowercase field_name}}`\n\nExample:\n- Input: `{{lowercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"mike\"\n\n### Uppercase\n\nTransforms the value to uppercase:\n\n`{{uppercase field_name}}`\n\nExample:\n- Input: `{{uppercase lead.first_name}}` with `lead.first_name` = \"Mike\"\n- Output: \"MIKE\"\n\n### Substring\n\nReturns a substring from the start position to the end position, or from the start position to the end of the string if no end position is provided:\n\n`{{substring field_name start=\"3\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"3\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"chael\"\n\n`{{substring field_name start=\"2\" end=\"4\"}}`\n\nExample:\n- Input: `{{substring lead.first_name start=\"2\" end=\"4\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"ich\"\n\n### Replace\n\nReplaces the pattern with the content of the replace option. The pattern can be a literal string or a regular expression using the `regexp()` option:\n\n`{{replace field_name pattern=\"Mi\" replace=\"At\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"Mi\" replace=\"At\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Atchael\"\n\n`{{replace field_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}`\n\nExample:\n- Input: `{{replace lead.first_name pattern=\"regexp(h.{3})\" replace=\"ke\"}}` with `lead.first_name` = \"Michael\"\n- Output: \"Micke\"\n\n### Extract\n\nExtracts all occurrences found with the regular expression in the pattern:\n\n`{{extract field_name pattern=\"\\$begin:math:display$(.*?)\\\\$end:math:display$\"}}`\n\nExample:\n- Input: `{{ extract foo pattern=\"(?\u003c=#)(\\\\w+)(?=#)\" }}` with `lead.first_name` = \"#John#Doe#Smith\"\n- Output: \"John Doe\"\n\n## Variable Math\n\nTo perform math operations, use the `math` helper: `{{ math \"1 + 1\" }}`\nresults in `2`. Of course, variables can also be used: `{{ math \"1 +\nlead.random_number\" }}` might result in `32` depending on the value\nof `lead.random_number`. The math expression accepts a pretty basic\ngrammar. Operators have the normal precedence:\n\n| Operator | Associativity | Description\n| ------------------------ | ------------- | ----------\n| (...) | None | Grouping\n| f(), x.y | Left | Function call, property access\n| ! | Left | Factorial\n| ^ | Right | Exponentiation\n| +, -, not, sqrt, etc. | Right | Unary prefix operators (see below for the full list)\n| \\*, /, % | Left | Multiplication, division, remainder\n| +, -, \\|\\| | Left | Addition, subtraction, concatenation\n| `==`, `!=`, `>=`, `\u003c=`, `>`, `\u003c`, `in` | Left | Equals, not equals, etc. `in` means \"is the left operand included in the right array operand?\" (disabled by default)\n| and | Left | Logical AND\n| or | Left | Logical OR\n| x ? y : z | Right | Ternary conditional (if x then y else z)\n\nThere are also several pre-defined functions:\n\n| Function | Description |\n| ------------- | ----------- |\n| sin(x) | Sine of x (x is in radians)\n| cos(x) | Cosine of x (x is in radians)\n| tan(x) | Tangent of x (x is… well, you know)\n| asin(x) | Arc sine of x (in radians)\n| acos(x) | Arc cosine of x (in radians)\n| atan(x) | Arc tangent of x (in radians)\n| sqrt(x) | Square root of x. Result is NaN (Not a Number) if x is negative.\n| log(x) | Natural logarithm of x (not base-10). It’s log instead of ln because that’s what JavaScript calls it.\n| abs(x) | Absolute value (magnitude) of x\n| ceil(x) | Ceiling of x — the smallest integer that’s >= x.\n| floor(x) | Floor of x — the largest integer that’s `\u003c=` x\n| round(x) | X, rounded to the nearest integer, using \"grade-school rounding\"\n| roundTo(x, n) | Rounds x to n places after the decimal point\n| exp(x) | ex (exponential/antilogarithm function with base e)\n| random(n) | Get a random number in the range [0, n). If n is zero, or not provided, it defaults to 1.\n| fac(n) | n! (factorial of n: “n * (n-1) * (n-2) * … * 2 * 1″)\n| min(a,b,...) | Get the smallest (“minimum”) number in the list\n| max(a,b,...) | Get the largest (“maximum”) number in the list\n| pyt(a, b) | Pythagorean function, i.e. the c in “c2 = a2 + b2“\n| pow(x, y) | xy. This is exactly the same as “x^y”. It’s just provided since it’s in the Math object from JavaScript\n| atan2(y, x) | arc tangent of x/y. i.e. the angle between (0, 0) and (x, y) in radians\n| if(c, a, b) | Function form of c ? a : b\n\n#### Example\n\nTo calculate the loan-to-value ratio, given a mortgage loan amount and\nthe value of the home: `{{ math \"(lead.mortgage.loan.amount /\nlead.mortgage.new_property_value) * 100\" }}%`. Note that this example\nexpresses the LTV as a percentage, first by calculating the percentage\nand then by appending the `%` character outside the variable\nplaceholder. This could instead be handled using\n[formatting](#variable-math-formatting).\n\n### Variable Math Formatting\n\nThe `math` helper supports the same options as the `format` helper for\nnumbers: `format` and `locale`. For example, to calculate the\nloan-to-value ratio and format it as a percentage: `{{ math\n\"lead.mortgage.loan.amount / lead.mortgage.new_property_value\"\nformat=\"0.[00]%\" }}`. This would return the LTV percentage with up to 2\ndecimal points (i.e. 72.93%) as a string value.\n\n## Variable Hashing\n\nLeadConduit supports a wide variety of hashing functions that can be\napplied to variables in a template. The helper name determines the\nhashing algorithm. For example, to use MD5 to hash the email address use:\n`{{ md5 lead.email }}`. All the following hashing algorithms are\nsupported:\n \n* md4\n* md5\n* ripemd\n* ripemd160\n* sha1\n* sha224\n* sha256\n* sha384\n* sha512\n* whirlpool\n \nMultiple values can be hashed together: `{{ md5 lead.email lead.phone_1 }}`. This can be used to salt the hash \nalso: `{{ md5 lead.email \"this is my salt\" }}`. The `salt` option can also be used. This is the equivalent of the \nlast example: `{{ md5 lead.email salt=\"this is my salt\" }}`. \n\nHashing supports multiple encodings using the `encoding` option:\n`{{ md5 lead.email encoding=\"base64\" }}` results in something like\n\"tkK0IXs0sejTvZFfxlxEUg==\". The following encodings are supported:\n \n* `hex` (default)\n* `base64`\n* `latin1`\n","x-tags":["Templates"],"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3.items.[INDEX]","typeLabel":"string"},"description":"The right-hand value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","example":"TX","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv.oneOf.3","typeLabel":"string[]"}],"isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rhv","typeLabel":"string | number | boolean | string[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.0","typeLabel":"Binary Rule · object"},{"type":"object","title":"Unary Rule","required":["lhv","op"],"x-tags":["Rules"],"properties":{"lhv":{"type":"string","title":"Template","description":"The value to be evaluated ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"example":"lead.email","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.lhv","typeLabel":"string"},"op":{"type":"string","enum":["is blank","is not blank","is true","is false","is not true","is not false","format is valid","format is invalid","is obscene","is not obscene"],"x-enumDescriptions":{"is blank":"Is the `lhv` missing or empty?","is not blank":"Does the `lhv` contain a value?","is true":"Does the `lhv` evaluate to `true`?","is false":"Does the `lhv` evaluate to `false`?","format is valid":"The `lhv` was successfully interpreted as a value of its specified type.","format is invalid":"The `lhv` could not be interpreted as a value of its specified type.","is obscene":"Does the `lhv` contain obscene language?","is not obscene":"Does the `lhv` contain no obscene language?"},"example":"is not blank","description":"Unary operators evaluate the `lhv`.\n","isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.op","typeLabel":"enum\u003cstring>"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"1aacd0","readOnly":true,"description":"ID for this rule","uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.id","typeLabel":"string"},"rule_set":{"oneOf":[{}],"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.rule_set","typeLabel":"any"},"metadata":{"oneOf":[{"type":"object","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.0","typeLabel":"Metadata · object"},{"type":"null","title":"Metadata","description":"Not available yet. String values that LeadConduit stores on a source, step or rule and does\nnot interpret. Keys are lowercase snake case, up to 64 characters.\n","maxProperties":20,"x-internal":true,"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1.metadata","typeLabel":"Metadata · object | null"}},"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX].oneOf.1","typeLabel":"Unary Rule · object"},{}],"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules.items.[INDEX]","typeLabel":"Binary Rule · object | Unary Rule · object"},"isRequired":true,"uniqueKey":"pricing.prices.items.[INDEX].rule_set.rules","typeLabel":"(Binary Rule · object | Unary Rule · object)[]"},"id":{"type":"string","pattern":"^[0-9a-zA-Z]{6}$","example":"0d144a","readOnly":true,"description":"The ID of the rule set in this flow","uniqueKey":"pricing.prices.items.[INDEX].rule_set.id","typeLabel":"string"}},"additionalProperties":false,"required":["op","rules"],"uniqueKey":"pricing.prices.items.[INDEX].rule_set","typeLabel":"Rule Set · object"}},"required":["amount"],"additionalProperties":false,"uniqueKey":"pricing.prices.items.[INDEX]","typeLabel":"object"},"uniqueKey":"pricing.prices","typeLabel":"object[]"}},"additionalProperties":false,"uniqueKey":"pricing","typeLabel":"object"},"list_checks":{"description":"Check the lead against SuppressionList lists to see if it's a duplicate, and existing customer, or is on the\ndo-not-call list.\n","type":"object","properties":{"duplicate":{"type":"object","properties":{"value":{"type":"string","title":"Template","description":"Is this value on the list? ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"uniqueKey":"list_checks.duplicate.value","typeLabel":"string"},"list_name":{"description":"The name of the SuppressionList list to check","type":"string","minLength":1,"uniqueKey":"list_checks.duplicate.list_name","typeLabel":"string"},"lookback":{"oneOf":[{"type":"null","description":"Only query for the value in the list this far back","uniqueKey":"list_checks.duplicate.lookback.oneOf.0","typeLabel":"null"},{"type":"object","description":"Only query for the value in the list this far back","required":["value","interval"],"properties":{"value":{"description":"The number of units that define the look-back window","type":"number","isRequired":true,"uniqueKey":"list_checks.duplicate.lookback.oneOf.1.value","typeLabel":"number"},"interval":{"description":"Each unit defined in the `value` is one of these durations","type":"string","enum":["year","month","week","day","hour","minute"],"isRequired":true,"uniqueKey":"list_checks.duplicate.lookback.oneOf.1.interval","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"list_checks.duplicate.lookback.oneOf.1","typeLabel":"object"}],"uniqueKey":"list_checks.duplicate.lookback","typeLabel":"null | object"}},"description":"Query a SuppressionList to determine if the lead is a on the duplicate list (use `suppressionlist.is_duplicate` rules)","example":{"value":"{{lead.phone}}","list_name":"duplicates","lookback":{"value":7,"interval":"day"}},"uniqueKey":"list_checks.duplicate","typeLabel":"object"},"existing_customer":{"type":"object","properties":{"value":{"type":"string","title":"Template","description":"Is this value on the list? ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"uniqueKey":"list_checks.existing_customer.value","typeLabel":"string"},"list_name":{"description":"The name of the SuppressionList list to check","type":"string","minLength":1,"uniqueKey":"list_checks.existing_customer.list_name","typeLabel":"string"},"lookback":{"oneOf":[{"type":"null","description":"Only query for the value in the list this far back","uniqueKey":"list_checks.existing_customer.lookback.oneOf.0","typeLabel":"null"},{"type":"object","description":"Only query for the value in the list this far back","required":["value","interval"],"properties":{"value":{"description":"The number of units that define the look-back window","type":"number","isRequired":true,"uniqueKey":"list_checks.existing_customer.lookback.oneOf.1.value","typeLabel":"number"},"interval":{"description":"Each unit defined in the `value` is one of these durations","type":"string","enum":["year","month","week","day","hour","minute"],"isRequired":true,"uniqueKey":"list_checks.existing_customer.lookback.oneOf.1.interval","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"list_checks.existing_customer.lookback.oneOf.1","typeLabel":"object"}],"uniqueKey":"list_checks.existing_customer.lookback","typeLabel":"null | object"}},"description":"Query a SuppressionList to determine if the lead is a on the list of existing customers (use `suppressionlist.is_existing_customer` rules)","example":{"value":"{{lead.email}}","list_name":"customer_emails","lookback":null},"uniqueKey":"list_checks.existing_customer","typeLabel":"object"},"dnc":{"type":"object","properties":{"value":{"type":"string","title":"Template","description":"Is this value on the list? ([templating](https://developers.activeprospect.com/api-reference/leadconduit/templates) is supported)","x-tags":["Templates"],"uniqueKey":"list_checks.dnc.value","typeLabel":"string"},"list_name":{"description":"The name of the SuppressionList list to check","type":"string","minLength":1,"uniqueKey":"list_checks.dnc.list_name","typeLabel":"string"},"lookback":{"oneOf":[{"type":"null","description":"Only query for the value in the list this far back","uniqueKey":"list_checks.dnc.lookback.oneOf.0","typeLabel":"null"},{"type":"object","description":"Only query for the value in the list this far back","required":["value","interval"],"properties":{"value":{"description":"The number of units that define the look-back window","type":"number","isRequired":true,"uniqueKey":"list_checks.dnc.lookback.oneOf.1.value","typeLabel":"number"},"interval":{"description":"Each unit defined in the `value` is one of these durations","type":"string","enum":["year","month","week","day","hour","minute"],"isRequired":true,"uniqueKey":"list_checks.dnc.lookback.oneOf.1.interval","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"list_checks.dnc.lookback.oneOf.1","typeLabel":"object"}],"uniqueKey":"list_checks.dnc.lookback","typeLabel":"null | object"}},"description":"Query a SuppressionList to determine if the lead is on the do-not-call list (use `suppressionlist.is_dnc` rules)","example":{"value":"{{lead.phone}}","list_name":"do_not_call","lookback":null},"uniqueKey":"list_checks.dnc","typeLabel":"object"}},"additionalProperties":false,"uniqueKey":"list_checks","typeLabel":"object"},"destinations":{"type":"array","items":{"x-tags":["Destinations","Flows"],"type":"object","description":"An internal representation of a Prismatic instance.\n","properties":{"name":{"description":"A customizable name of the destination.","type":"string","example":"Salesforce","uniqueKey":"destinations.items.[INDEX].name","typeLabel":"string"},"integration_name":{"type":"string","description":"The name of the integration as published in the Marketplace.","uniqueKey":"destinations.items.[INDEX].integration_name","typeLabel":"string"},"integration_icon_url":{"type":"string","description":"Pre-signed URL for the integration icon.","uniqueKey":"destinations.items.[INDEX].integration_icon_url","typeLabel":"string"},"instance_id":{"description":"The Prismatic instance ID.","type":"string","uniqueKey":"destinations.items.[INDEX].instance_id","typeLabel":"string"},"actions":{"description":"A list of actions available in the configured instance. These map to Prismatic \"flows\" within an instance.","type":"array","items":{"type":"object","properties":{"name":{"description":"The name of the flow, or \"action\", available in the configured instance. One instance can have multiple flows.","type":"string","example":"Add Lead","uniqueKey":"destinations.items.[INDEX].actions.items.[INDEX].name","typeLabel":"string"},"action_id":{"description":"The Prismatic flow ID.","type":"string","example":"Add Lead","uniqueKey":"destinations.items.[INDEX].actions.items.[INDEX].action_id","typeLabel":"string"},"webhook_url":{"description":"The Prismatic webhook URL. This URL will invoke the Prismatic flow defined by the configured instance.","type":"string","uniqueKey":"destinations.items.[INDEX].actions.items.[INDEX].webhook_url","typeLabel":"string"}},"uniqueKey":"destinations.items.[INDEX].actions.items.[INDEX]","typeLabel":"object"},"uniqueKey":"destinations.items.[INDEX].actions","typeLabel":"object[]"},"flow_usages":{"description":"Contains data on flows in which the destination is used.\nThis field is optional and is **only** included when the `include=flow_usages` query parameter is included in the request.\n","type":"object","properties":{"count":{"description":"The total number of flows in which the destination is used.","type":"integer","uniqueKey":"destinations.items.[INDEX].flow_usages.count","typeLabel":"integer"},"flows":{"description":"A list of flows in which the destination is used.","type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The flow ID","pattern":"^[0-9a-fA-F]{24}$","readOnly":true,"example":"5fd4371e940df5a34a3888b2","uniqueKey":"destinations.items.[INDEX].flow_usages.flows.items.[INDEX].id","typeLabel":"string"},"name":{"description":"The name of the flow","type":"string","uniqueKey":"destinations.items.[INDEX].flow_usages.flows.items.[INDEX].name","typeLabel":"string"}},"uniqueKey":"destinations.items.[INDEX].flow_usages.flows.items.[INDEX]","typeLabel":"object"},"uniqueKey":"destinations.items.[INDEX].flow_usages.flows","typeLabel":"object[]"}},"uniqueKey":"destinations.items.[INDEX].flow_usages","typeLabel":"object"}},"uniqueKey":"destinations.items.[INDEX]","typeLabel":"object"},"uniqueKey":"destinations","typeLabel":"object[]"},"ping_enabled":{"type":"boolean","default":false,"uniqueKey":"ping_enabled","typeLabel":"boolean"},"ping_limits":{"title":"Ping Limits","type":"array","items":{"x-tags":["Caps and Limits"],"title":"Ping Limit","description":"The ping limit configuration is defined in a flow on a source, or directly on the flow itself. The configuration controls the behavior of the ping limit by setting the maximum and the duration. The counter for a ping limit is kept as a standalone record which shares ping limit's ID.","type":"object","properties":{"id":{"type":"string","description":"24 character alpha-numeric BSON identifier","pattern":"^[0-9a-fA-F]{24}$","readOnly":true,"example":"5fd4371e940df5a34a3888b2","uniqueKey":"ping_limits.items.[INDEX].id","typeLabel":"string"},"name":{"type":"string","description":"The human-readable name of the ping limit","uniqueKey":"ping_limits.items.[INDEX].name","typeLabel":"string"},"maximum":{"type":"integer","description":"The number of pings that will be accepted","uniqueKey":"ping_limits.items.[INDEX].maximum","typeLabel":"integer"},"duration":{"type":"integer","description":"The number duration_units the ping limit persists for","uniqueKey":"ping_limits.items.[INDEX].duration","typeLabel":"integer"},"duration_units":{"type":"string","description":"The unit of time the ping limit persists for: minute, hour, day, week, or month","uniqueKey":"ping_limits.items.[INDEX].duration_units","typeLabel":"string"},"time_zone":{"type":"string","description":"The time zone in which ping limit resets","example":"America/New_York","uniqueKey":"ping_limits.items.[INDEX].time_zone","typeLabel":"string"},"created_at":{"type":"string","format":"date-time","description":"Read-only time the ping limit was created","readOnly":true,"uniqueKey":"ping_limits.items.[INDEX].created_at","typeLabel":"string\u003cdate-time>"}},"uniqueKey":"ping_limits.items.[INDEX]","typeLabel":"Ping Limit · object"},"uniqueKey":"ping_limits","typeLabel":"Ping Limit · object[]"},"pricing_service":{"type":"object","title":"Pricing Service Config","description":"The configuration required on a Source or Flow to define a Pricing Service for lead pricing.\n","properties":{"service_id":{"type":"string","description":"The unique identifier for a configured pricing service","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"pricing_service.service_id","typeLabel":"string"},"fallback_price":{"type":"number","isRequired":true,"uniqueKey":"pricing_service.fallback_price","typeLabel":"number"}},"required":["service_id","fallback_price"],"additionalProperties":false,"uniqueKey":"pricing_service","typeLabel":"Pricing Service Config · object"},"firehose":{"type":"object","description":"Firehose configuration for exporting event data to cloud storage. Supports a legacy flat format (AWS S3 only) and a service-based format that allows multiple cloud storage providers.\n","properties":{"enabled":{"type":"boolean","description":"Is the firehose enabled for this flow?","isRequired":true,"uniqueKey":"firehose.enabled","typeLabel":"boolean"},"credential_id":{"type":"string","description":"The ID of the credential storing the AWS keys (legacy format)","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","uniqueKey":"firehose.credential_id","typeLabel":"string"},"bucket":{"type":"string","description":"The name of the S3 bucket (legacy format)","pattern":"^(?=^.{3,63}$)(?!^(\\d+\\.?)+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9]))$","uniqueKey":"firehose.bucket","typeLabel":"string"},"prefix":{"type":"string","description":"Optional. If provided, files written to S3 will be written as \u0026lt;prefix>/\u0026lt;lead id>/\u0026lt;event id>.json (legacy format)","uniqueKey":"firehose.prefix","typeLabel":"string"},"services":{"type":"object","description":"Service-based configuration allowing multiple cloud storage providers","properties":{"aws":{"type":"object","description":"AWS S3 firehose service configuration","properties":{"enabled":{"type":"boolean","description":"Is the AWS S3 firehose enabled?","isRequired":true,"uniqueKey":"firehose.services.aws.enabled","typeLabel":"boolean"},"credential_id":{"type":"string","description":"The ID of the credential storing the AWS keys","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"firehose.services.aws.credential_id","typeLabel":"string"},"bucket":{"type":"string","description":"The name of the S3 bucket","pattern":"^(?=^.{3,63}$)(?!^(\\d+\\.?)+$)(^(([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9])\\.)*([a-z0-9]|[a-z0-9][a-z0-9\\-]*[a-z0-9]))$","isRequired":true,"uniqueKey":"firehose.services.aws.bucket","typeLabel":"string"},"prefix":{"type":"string","description":"Optional. If provided, files written to S3 will be written as \u0026lt;prefix>/\u0026lt;lead id>/\u0026lt;event id>.json","uniqueKey":"firehose.services.aws.prefix","typeLabel":"string"}},"required":["credential_id","bucket","enabled"],"additionalProperties":false,"uniqueKey":"firehose.services.aws","typeLabel":"object"},"azure":{"type":"object","description":"Azure Blob Storage firehose service configuration","properties":{"enabled":{"type":"boolean","description":"Is the Azure Blob Storage firehose enabled?","isRequired":true,"uniqueKey":"firehose.services.azure.enabled","typeLabel":"boolean"},"credential_id":{"type":"string","description":"The ID of the credential storing the Azure connection string","pattern":"^[0-9a-fA-F]{24}$","example":"5fd4371e940df5a34a3888b2","isRequired":true,"uniqueKey":"firehose.services.azure.credential_id","typeLabel":"string"},"bucket":{"type":"string","description":"The name of the Azure Blob Storage container","isRequired":true,"uniqueKey":"firehose.services.azure.bucket","typeLabel":"string"},"connection_string":{"type":"string","description":"The Azure Blob Storage connection string","uniqueKey":"firehose.services.azure.connection_string","typeLabel":"string"},"prefix":{"type":"string","description":"Optional. If provided, files written to Azure will be written as \u0026lt;prefix>/\u0026lt;lead id>/\u0026lt;event id>.json","uniqueKey":"firehose.services.azure.prefix","typeLabel":"string"}},"required":["credential_id","bucket","enabled"],"additionalProperties":false,"uniqueKey":"firehose.services.azure","typeLabel":"object"}},"additionalProperties":false,"uniqueKey":"firehose.services","typeLabel":"object"}},"required":["enabled"],"uniqueKey":"firehose","typeLabel":"object"},"metadata":{"oneOf":[{"type":"object","title":"FlowMetadata","description":"Not available yet. Metadata on a flow, with the same keys and limits as `Metadata`.\n`managed_by` records what manages the flow; absent means the account does.\n","maxProperties":20,"x-internal":true,"properties":{"managed_by":{"type":"string","enum":["account","offers_engine"],"uniqueKey":"metadata.oneOf.0.managed_by","typeLabel":"enum\u003cstring>"}},"additionalProperties":false,"uniqueKey":"metadata.oneOf.0","typeLabel":"FlowMetadata · object"},{"type":"null","title":"FlowMetadata","description":"Not available yet. Metadata on a flow, with the same keys and limits as `Metadata`.\n`managed_by` records what manages the flow; absent means the account does.\n","maxProperties":20,"x-internal":true,"properties":{"managed_by":{"type":"string","enum":["account","offers_engine"]}},"additionalProperties":false,"uniqueKey":"metadata.oneOf.1","typeLabel":"null"}],"uniqueKey":"metadata","typeLabel":"FlowMetadata · object | null"},"level":{"type":"string","description":"The level of the flow, e.g. 'minimal' for buyer accounts","readOnly":true,"uniqueKey":"level","typeLabel":"string"},"created_at":{"type":"string","format":"date-time","readOnly":true,"uniqueKey":"created_at","typeLabel":"string\u003cdate-time>"},"updated_at":{"type":"string","format":"date-time","readOnly":true,"uniqueKey":"updated_at","typeLabel":"string\u003cdate-time>"}},"additionalProperties":false,"required":["enabled","name","fields","sources","steps"],"uniqueKey":"","typeLabel":"object","example":{"title":"Example","value":{"name":"Sales Leads","enabled":true,"fields":["first_name","last_name","email","phone_1","address_1","city","state","postal_code","trustedform_cert_url"],"sources":[{"integration":{"module_id":"leadconduit-salesforce.outbound.create_contact","mappings":[{"property":"\u003cstring>","value":"\u003cstring>","id":"1aacd0"}]},"entity":{"id":"5fd4371e940df5a34a3888b2","name":"\u003cstring>","time_zone":"America/New_York"},"id":"1aacd0","caps":[{"id":"5fd438f91f0d12766e2bfee5","type":"volume","name":"Monthly leads from TX","maximum":1200,"duration":1,"caps":"\u003carray>","time_zone":"America/New_York","reason":"\u003cstring>","created_at":"2020-11-23T11:41:52Z"}],"ping_limits":[{"id":"5fd4371e940df5a34a3888b2","name":"\u003cstring>","maximum":123,"duration":123,"duration_units":"\u003cstring>","time_zone":"America/New_York","created_at":"2023-11-07T05:31:56Z"}],"credential_id":"5fd4371e940df5a34a3888b2","pricing":{"override":true,"prices":[{"amount":123,"id":"\u003cunknown>"}]},"enabled":true,"authentication_required":true,"metadata":{}}],"steps":[{"type":"calculated","fields":[{"name":"\u003cstring>","rules":[{"value":"\u003cstring>","rule_set":{"rules":[{"lhv":"lead.state","op":"is equal to","rhv":"TX","id":"1aacd0","rule_set":"\u003cunknown>","metadata":{}}],"id":"0d144a"},"id":"1aacd0"}],"fallback":"\u003cstring>","id":"1aacd0"}],"id":"1aacd0","description":"\u003cstring>","notes":"\u003cstring>","enabled":true,"metadata":{}}],"id":"5fd4371e940df5a34a3888b2","errors":{},"caps":[{"id":"5fd438f91f0d12766e2bfee5","type":"volume","name":"Monthly leads from TX","maximum":1200,"duration":1,"caps":"\u003carray>","time_zone":"America/New_York","reason":"\u003cstring>","created_at":"2020-11-23T11:41:52Z"}],"pricing":{"override":true,"prices":[{"amount":123,"id":"\u003cunknown>"}]},"list_checks":{"duplicate":{"value":"{{lead.phone}}","list_name":"duplicates","lookback":{"value":7,"interval":"day"}},"existing_customer":{"value":"{{lead.email}}","list_name":"customer_emails","lookback":null},"dnc":{"value":"{{lead.phone}}","list_name":"do_not_call","lookback":null}},"destinations":[{"name":"Salesforce","integration_name":"\u003cstring>","integration_icon_url":"\u003cstring>","instance_id":"\u003cstring>","actions":[{"name":"Add Lead","action_id":"Add Lead","webhook_url":"\u003cstring>"}],"flow_usages":{"count":123,"flows":[{"id":"5fd4371e940df5a34a3888b2","name":"\u003cstring>"}]}}],"ping_enabled":false,"ping_limits":[{"id":"5fd4371e940df5a34a3888b2","name":"\u003cstring>","maximum":123,"duration":123,"duration_units":"\u003cstring>","time_zone":"America/New_York","created_at":"2023-11-07T05:31:56Z"}],"metadata":{},"level":"\u003cstring>","created_at":"2023-11-07T05:31:56Z","updated_at":"2023-11-07T05:31:56Z"}}},"originalFileLocation":"LeadConduit-API/v1/bundle/master/leadconduit_api.json"},"subdomain":"activeprospectinc","siteName":"ActiveProspect Developer Documentation","title":"Flow - ActiveProspect Developer Documentation","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-03T16:52:46.324Z","originalFileLocation":"api-reference/leadconduit/flows/flow.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"application-name\" content=\"ActiveProspect Developer Documentation\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_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/activeprospectinc/-voIGRv_PaCQr-Wj/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Flow - ActiveProspect Developer Documentation\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"ActiveProspect Developer Documentation\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://activeprospectinc.mintlify.app/_mintlify/api/og/v2?division=Flows\u0026amp;title=Flow\u0026amp;theme=82b92e625aa25be6cc045629\u0026amp;signature=ca2299d262b7723d2091a2a34474de011eac61649557d0a60cd50a5d6d42a48b\">\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=\"Flow - ActiveProspect Developer Documentation\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://activeprospectinc.mintlify.app/_mintlify/api/og/v2?division=Flows\u0026amp;title=Flow\u0026amp;theme=82b92e625aa25be6cc045629\u0026amp;signature=ca2299d262b7723d2091a2a34474de011eac61649557d0a60cd50a5d6d42a48b\">\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/activeprospectinc/-voIGRv_PaCQr-Wj/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"ActiveProspect Developer Documentation\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#22a7f0\">\u003clink data-mint-head rel=\"canonical\" href=\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/leadconduit/flows/flow.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://developers.activeprospect.com/#organization\",\"name\":\"ActiveProspect Developer Documentation\",\"url\":\"https://developers.activeprospect.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/activeprospectinc/ttzTIJYOTNQPAJMy/logo/activeprospect_logo.svg?fit=max\u0026auto=format\u0026n=ttzTIJYOTNQPAJMy\u0026q=85\u0026s=9c7503c7631642aa1f7288ae35cc02cc\"}},{\"@type\":\"WebSite\",\"@id\":\"https://developers.activeprospect.com#website\",\"name\":\"ActiveProspect Developer Documentation\",\"url\":\"https://developers.activeprospect.com\",\"publisher\":{\"@id\":\"https://developers.activeprospect.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow#webpage\",\"url\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow\",\"name\":\"Flow\",\"dateModified\":\"2026-11-03T16:52:46.324Z\",\"isPartOf\":{\"@id\":\"https://developers.activeprospect.com#website\"},\"breadcrumb\":{\"@id\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"API Documentation\",\"item\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/destination\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"API Endpoints\",\"item\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/destination\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Flows\",\"item\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Flow\",\"item\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow#apireference\",\"headline\":\"Flow\",\"name\":\"Flow\",\"url\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow\",\"mainEntityOfPage\":{\"@id\":\"https://developers.activeprospect.com/api-reference/leadconduit/flows/flow#webpage\"},\"dateModified\":\"2026-11-03T16:52:46.324Z\",\"publisher\":{\"@id\":\"https://developers.activeprospect.com/#organization\"},\"isPartOf\":{\"@id\":\"https://developers.activeprospect.com#website\"}}]}\u003c/script>","siteName":"ActiveProspect Developer Documentation","nav":{"global":null,"tabs":[{"tab":"Welcome","pages":[{"title":"ActiveProspect Documentation","mode":"center","href":""}]},{"tab":"TrustedForm","pages":[{"title":"Getting Started","href":"/pages/trustedform/getting-started"},{"title":"Implementing the TrustedForm Certify Web SDK","href":"/pages/trustedform/implementing-trustedform-certify"},{"title":"Adding TrustedForm Consent Tags","href":"/pages/trustedform/consent-tagging"},{"group":"API Documentation","pages":[{"title":"Authentication","href":"/pages/trustedform/authentication"},{"group":"TrustedForm API 4.0","pages":[{"group":"Certificate URL","root":{"title":"Certificate URL","href":"/api-reference/trustedform/v4/certificate-url"},"pages":[{"title":"Run Certificate Operations","deprecated":null,"version":null,"openapi":"/api-reference/claims_api-v4.yaml post /{cert_id}","href":"/api-reference/certificate-url/run-certificate-operations"}]},{"group":"Operations","root":{"title":"Operations","href":"/api-reference/trustedform/v4/operations"},"pages":[{"group":"Match Lead","root":{"title":"Match Lead","href":"/api-reference/trustedform/v4/operations/match-lead"},"pages":[{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/MatchLeadParameters"},{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/MatchLeadResult"}]},{"group":"Retain","root":{"title":"Retain","href":"/api-reference/trustedform/v4/operations/retain"},"pages":[{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/RetainParameters"},{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/RetainResult"}]},{"group":"Insights","root":{"title":"Insights","href":"/api-reference/trustedform/v4/operations/insights"},"pages":[{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/InsightsParameters"},{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/InsightsResult"}]},{"group":"Verify","root":{"title":"Verify","href":"/api-reference/trustedform/v4/operations/verify"},"pages":[{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/VerifyParameters"},{"title":null,"href":"/api-reference/trustedform/v4/operations/schemas/VerifyResult"}]}]},{"group":"Certificate","pages":[{"title":"Types","href":"/api-reference/trustedform/v4/certificate/types"},{"title":"Sending on Ping","href":"/api-reference/trustedform/v4/certificate/sending-on-ping"}]}]},{"title":"Validate API","href":"/pages/trustedform/validating-certificates"},{"group":"TrustedForm API 3.0","pages":[{"title":"Overview","href":"/api-reference/trustedform/v3/overview"},{"group":"Retrieving Insights","pages":[{"title":"Retrieve Certificate Insights","deprecated":null,"version":null,"openapi":"/api-reference/trustedform_v3.json post /{cert_id_}","href":"/api-reference/retrieving-insights/retrieve-certificate-insights"}]},{"group":"Viewing Certificates","pages":[{"title":"Viewing a Certificate","deprecated":null,"version":null,"openapi":"/api-reference/trustedform_v3.json get /{cert_id}","href":"/api-reference/viewing-certificates/viewing-a-certificate"}]},{"group":"Claiming Certificates","pages":[{"title":"Claiming a Certificate","deprecated":null,"version":null,"openapi":"/api-reference/trustedform_v3.json post /{cert_id}","href":"/api-reference/claiming-certificates/claiming-a-certificate"}]},{"group":"TrustedForm Certificate Check-in","pages":[{"title":"Check-in","deprecated":null,"version":null,"openapi":"/api-reference/trustedform_v3.json post /{cert_id}/check_in","href":"/api-reference/trustedform-certificate-check-in/check-in"}]},{"group":"Ping","pages":[{"title":"Retrieving Ping Data","deprecated":true,"version":null,"openapi":"/api-reference/trustedform_v3.json post /{cert_id}/ping","href":"/api-reference/ping/retrieving-ping-data"},{"title":"Generate Ping URL","deprecated":true,"version":null,"openapi":"/api-reference/trustedform_v3.json get /{cert_id}/ping_url","href":"/api-reference/ping/generate-ping-url"}]}]},{"group":"TrustedForm API v2.0","pages":[{"title":"Overview","href":"/api-reference/trustedform/v2/overview"},{"group":"Ping","pages":[{"title":"Retrieve Ping Data","deprecated":true,"version":null,"openapi":"/api-reference/trustedform_v2.yaml get /{cert_id}/ping","href":"/api-reference/ping/retrieve-ping-data"}]},{"group":"Claiming Certificates","pages":[{"title":"Claiming Certificates","deprecated":null,"version":null,"openapi":"/api-reference/trustedform_v2.yaml post /{cert_id}","href":"/api-reference/claiming-certificates/claiming-certificates"}]}]}]}]},{"tab":"LeadConduit","pages":[{"title":"About","href":"/api-reference/leadconduit"},{"title":"Authentication","href":"/pages/leadconduit/authentication"},{"group":"API Documentation","pages":[{"group":"API Endpoints","pages":[{"group":"Flows","root":{"title":"Flows","href":"/api-reference/leadconduit/flows"},"pages":[{"title":null,"description":null,"href":"/api-reference/leadconduit/flows/destination"},{"title":null,"href":"/api-reference/leadconduit/flows/flow"},{"title":null,"description":null,"href":"/api-reference/leadconduit/flows/meta"},{"title":"Submission response","sidebarTitle":"Submission response","href":"/api-reference/leadconduit/flows/submission-response"},{"title":"Ping response","sidebarTitle":"Ping response","href":"/api-reference/leadconduit/flows/ping-response"},{"title":"List all flows","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows","href":"/api-reference/flows/list-all-flows"},{"title":"Update all flows","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /flows","href":"/api-reference/flows/update-all-flows"},{"title":"Create a new flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /flows","href":"/api-reference/flows/create-a-new-flow"},{"title":"Get a flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows/{id}","href":"/api-reference/flows/get-a-flow"},{"title":"Update an existing flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /flows/{id}","href":"/api-reference/flows/update-an-existing-flow"},{"title":"Delete an existing flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json delete /flows/{id}","href":"/api-reference/flows/delete-an-existing-flow"},{"title":"Deploy a saved flow to production","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /flows/{id}/deploy","href":"/api-reference/flows/deploy-a-saved-flow-to-production"},{"title":"List fields associated to the Flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows/{id}/fields","href":"/api-reference/flows/list-fields-associated-to-the-flow"},{"title":"Get flow field usages","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows/{id}/fields/usage","href":"/api-reference/flows/get-flow-field-usages"},{"title":"Retrieve metadata for a specific source within a flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows/{flow_id}/sources/{source_id}/meta","href":"/api-reference/flows/retrieve-metadata-for-a-specific-source-within-a-flow"},{"title":"Submit data to a source within a flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /flows/{flow_id}/sources/{source_id}/submit","href":"/api-reference/flows/submit-data-to-a-source-within-a-flow"},{"title":"Ping a source within a flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows/{flow_id}/sources/{source_id}/ping","href":"/api-reference/flows/ping-a-source-within-a-flow"},{"title":"Ping a source within a flow with a request body","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /flows/{flow_id}/sources/{source_id}/ping","href":"/api-reference/flows/ping-a-source-within-a-flow-with-a-request-body"}]},{"group":"Leads","root":{"title":"Leads","href":"/api-reference/leadconduit/leads"},"pages":[{"title":null,"href":"/api-reference/leadconduit/leads/event"},{"title":"List all events","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /events","href":"/api-reference/leads/list-all-events"},{"title":"List all events for exports","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /events","href":"/api-reference/leads/list-all-events-for-exports"},{"title":"Fetch a single event","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /events/{id}","href":"/api-reference/leads/fetch-a-single-event"}]},{"group":"Feedback","root":{"title":"Feedback","href":"/api-reference/leadconduit/feedback"},"pages":[{"title":"Feedback submission","sidebarTitle":"Feedback submission","href":"/api-reference/leadconduit/feedback/feedback-submission"},{"title":"Feedback result","sidebarTitle":"Feedback result","href":"/api-reference/leadconduit/feedback/feedback-submission-result"},{"title":"Submit feedback for a lead","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /feedback","href":"/api-reference/feedback/submit-feedback-for-a-lead"},{"title":"Submit feedback for a lead using query parameters","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /feedback","href":"/api-reference/feedback/submit-feedback-for-a-lead-using-query-parameters"},{"title":"Submit feedback for a lead using your own record ID","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /feedback/{recipient_name}","href":"/api-reference/feedback/submit-feedback-for-a-lead-using-your-own-record-id"}]},{"group":"Exports","root":{"title":"Exports","href":"/api-reference/leadconduit/exports"},"pages":[{"title":null,"href":"/api-reference/leadconduit/exports/export"},{"title":"List all exports","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /exports","href":"/api-reference/exports/list-all-exports"},{"title":"Create an export","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /exports","href":"/api-reference/exports/create-an-export"},{"title":"Get an export","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /exports/{id}","href":"/api-reference/exports/get-an-export"},{"title":"Get a download link for an export","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /exports/{id}/file","href":"/api-reference/exports/get-a-download-link-for-an-export"}]},{"group":"Fields","pages":[{"title":null,"href":"/api-reference/leadconduit/fields/field"},{"title":null,"href":"/api-reference/leadconduit/fields/type"},{"title":"List all fields","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /fields","href":"/api-reference/fields/list-all-fields"},{"title":"Create a field","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /fields","href":"/api-reference/fields/create-a-field"},{"title":"Get a field","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /fields/{id}","href":"/api-reference/fields/get-a-field"},{"title":"Update a field","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /fields/{id}","href":"/api-reference/fields/update-a-field"},{"title":"Delete a field","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json delete /fields/{id}","href":"/api-reference/fields/delete-a-field"},{"title":"List changes to a Field","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /fields/{id}/changelogs","href":"/api-reference/fields/list-changes-to-a-field"},{"title":"List data types","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /types","href":"/api-reference/fields/list-data-types"}]},{"group":"Entities","root":{"title":"Entities","href":"/api-reference/leadconduit/entities"},"pages":[{"title":null,"href":"/api-reference/leadconduit/entities/entity"},{"title":"List all entities","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /entities","href":"/api-reference/entities/list-all-entities"},{"title":"Create an entity","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /entities","href":"/api-reference/entities/create-an-entity"},{"title":"Get an entity","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /entities/{id}","href":"/api-reference/entities/get-an-entity"},{"title":"Update an entity","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /entities/{id}","href":"/api-reference/entities/update-an-entity"},{"title":"Delete an entity","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json delete /entities/{id}","href":"/api-reference/entities/delete-an-entity"},{"title":"List changes to an Entity","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /entities/{id}/changelogs","href":"/api-reference/entities/list-changes-to-an-entity"}]},{"group":"Packages","root":{"title":"Packages","href":"/api-reference/leadconduit/packages"},"pages":[{"title":"Package","sidebarTitle":"Package","href":"/api-reference/leadconduit/packages/package"},{"title":"List all integration packages","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /packages","href":"/api-reference/packages/list-all-integration-packages"},{"title":"Fetch a single integration package","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /packages/{id}","href":"/api-reference/packages/fetch-a-single-integration-package"}]},{"group":"Changelogs","root":{"title":"Changelogs","href":"/api-reference/leadconduit/changelogs"},"pages":[{"title":null,"href":"/api-reference/leadconduit/changelogs/changelog"},{"title":"List all changelogs","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /changelogs","href":"/api-reference/changelogs/list-all-changelogs"},{"title":"Get a changelog","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /changelogs/{id}","href":"/api-reference/changelogs/get-a-changelog"},{"title":"List changes to a Flow","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /flows/{id}/changelogs","href":"/api-reference/changelogs/list-changes-to-a-flow"}]},{"group":"Reports","pages":[{"title":null,"href":"/api-reference/leadconduit/reports/report"},{"title":"List all reports","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /reports","href":"/api-reference/reports/list-all-reports"},{"title":"Create a new report","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /reports","href":"/api-reference/reports/create-a-new-report"},{"title":"Fetch a single report","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /reports/{id}","href":"/api-reference/reports/fetch-a-single-report"},{"title":"Update an existing report","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /reports/{id}","href":"/api-reference/reports/update-an-existing-report"},{"title":"Delete a report","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json delete /reports/{id}","href":"/api-reference/reports/delete-a-report"},{"title":"Run a report","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /reports/{id}/run","href":"/api-reference/reports/run-a-report"}]},{"group":"Caps and Limits","root":{"title":"Caps and Limits","href":"/api-reference/leadconduit/caps-and-limits"},"pages":[{"title":null,"href":"/api-reference/leadconduit/caps-and-limits/cap"},{"title":null,"href":"/api-reference/leadconduit/caps-and-limits/cap-counter"},{"title":null,"href":"/api-reference/leadconduit/caps-and-limits/pinglimit"},{"title":null,"href":"/api-reference/leadconduit/caps-and-limits/pinglimit-counter"},{"title":"List all cap counters","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /caps","href":"/api-reference/caps-and-limits/list-all-cap-counters"},{"title":"Get a cap counter","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /caps/{id}","href":"/api-reference/caps-and-limits/get-a-cap-counter"},{"title":"List all ping limit counters","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /ping_limits","href":"/api-reference/caps-and-limits/list-all-ping-limit-counters"},{"title":"Fetch a ping limit counter","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /ping_limits/{id}","href":"/api-reference/caps-and-limits/fetch-a-ping-limit-counter"}]},{"group":"Firehose","root":{"title":"Firehose","href":"/api-reference/leadconduit/firehose"},"pages":[{"title":"Test firehose's ability to write to AWS S3 or Azure Blob Storage","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /firehose","href":"/api-reference/firehose/test-firehoses-ability-to-write-to-aws-s3-or-azure-blob-storage"}]},{"group":"Routers","pages":[{"title":null,"href":"/api-reference/leadconduit/router"},{"title":"List all routers","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /routers","href":"/api-reference/routers/list-all-routers"},{"title":"Create a router","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /routers","href":"/api-reference/routers/create-a-router"},{"title":"Get a router","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /routers/{id}","href":"/api-reference/routers/get-a-router"},{"title":"Update a router","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /routers/{id}","href":"/api-reference/routers/update-a-router"},{"title":"Submit a lead to a router","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /routers/{router_id}/route","href":"/api-reference/routers/submit-a-lead-to-a-router"},{"title":"Submit a lead to a router using query parameters","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /routers/{router_id}/route","href":"/api-reference/routers/submit-a-lead-to-a-router-using-query-parameters"}]},{"group":"Account","root":{"title":"Account","href":"/api-reference/leadconduit/account"},"pages":[{"title":null,"href":"/api-reference/leadconduit/account/account"},{"title":null,"href":"/api-reference/leadconduit/account/credential"},{"title":"Get account","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /account","href":"/api-reference/account/get-account"},{"title":"Update account","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /account","href":"/api-reference/account/update-account"},{"title":"List all credentials","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /credentials","href":"/api-reference/account/list-all-credentials"},{"title":"Create a new credential","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /credentials","href":"/api-reference/account/create-a-new-credential"},{"title":"Get a credential","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /credentials/{id}","href":"/api-reference/account/get-a-credential"},{"title":"Update a credential","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json put /credentials/{id}","href":"/api-reference/account/update-a-credential"},{"title":"Delete a credential","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json delete /credentials/{id}","href":"/api-reference/account/delete-a-credential"}]},{"group":"Connections","root":{"title":"Connections","href":"/api-reference/leadconduit/connections"},"pages":[{"title":"List connections","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /connections","href":"/api-reference/connections/list-connections"},{"title":"Repair: materialize a missing LC connection","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json post /connections","href":"/api-reference/connections/repair:-materialize-a-missing-lc-connection"},{"title":"Get connection by ID","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /connections/{id}","href":"/api-reference/connections/get-connection-by-id"}]},{"group":"System","pages":[{"title":null,"href":"/api-reference/leadconduit/system/status"},{"title":"Get system status","deprecated":null,"version":null,"openapi":"/api-reference/leadconduit_api.json get /status","href":"/api-reference/system/get-system-status"}]}]}]},{"group":"Concepts","pages":[{"group":"Rules","root":{"title":"Rules","href":"/api-reference/leadconduit/rules"},"pages":[{"title":null,"href":"/api-reference/leadconduit/rules/rule"},{"title":null,"href":"/api-reference/leadconduit/rules/rule-set"}]},{"group":"Variables","root":{"title":"Variables","href":"/api-reference/leadconduit/variables"},"pages":[{"title":null,"href":"/api-reference/leadconduit/variables/variables"}]},{"title":"Types","href":"/api-reference/leadconduit/types"},{"title":"Templates","href":"/api-reference/leadconduit/templates"}]}]}]},"basePath":"","title":"Flow - ActiveProspect Developer Documentation","buildId":"dpl_345ReqzYaAjzS9QpeJemsKdb7KDj","deploymentId":"dpl_345ReqzYaAjzS9QpeJemsKdb7KDj","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-C8RPHPxo.js","utils-0BK-9q6z.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DfjzsUJT.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-B4v9psJ4.js","snippetPresets-CpTQv-Ez.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-BNP-Fvr0.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-BSgu6h1D.js","shallow-Biv1i9Gs.js","getApiPlaygroundDisplay-BoGOXhtF.js","CodeSnippet-DvQoT18_.js","CodeSnippets-Dnpa15xT.js","Page-Buji1S4J.js","getPastedJson-xAIyhUFE.js","icon-S6FBih11.js","MethodPill-SaYeUZyk.js","DuplicateIcon-Cs-p3v2Q.js","createIcon-DjCFEoHq.js","DynamicMarkdown-BcnBltEQ.js","SectionHeading-BUBl0eEF.js","axios-vUo_bRtp.js","Markdown-h4cOoD8d.js","clsx-B2v50t8t.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-DJnKvr0g.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-BHrrjR1K.js"]}