Params and templates
Map values into a destination — params from a field or a fixed value, required params, {{…}} variables in URLs, headers, bodies and texts, and how each place encodes them for you.
Destinations work with two tools: params, the named values a destination carries, and templates, the {{…}} variables you write in its URLs, headers, bodies and texts.
Params
{
"params": {
"message": { "from": "state.message", "required": true },
"route": { "from": "result.route" },
"lead_score": { "from": "composites.lead_score" },
"team": { "value": "inbound" }
}
}A param takes its value from a field of the run (from) or is a fixed value (value): a string of up to 500 characters, a number, true, false or null. A destination has up to 30 params, named with letters, digits and _ — up to 48 characters, not starting with a digit.
Sources
from | Value |
|---|---|
state | The whole state: an object, a string or an array. |
state.<field> | A field declared in an object state schema. |
result.<question> | The answer: an option, a level label or a probability. |
confidence.<question> | The answer's confidence, 0 to 1. |
scores.<question> | The weighted level of a score question. |
composites.<key> | A composite's value. |
action | The final action: continue, block, escalate or fallback. |
decision.slug | The decision's slug. |
decision.version | The version that answered — null in the Playground, which runs the draft. |
execution.id | The run's exec_… ID. |
Values keep their JSON type: confidence.route is a number, state an object. A value that doesn't exist — an optional field the caller didn't send, any answer after an engine-error fallback — is null.
Required params
Mark a param required when the destination makes no sense without it — a CRM lead without an e-mail. When it resolves to null or an empty string, the destination doesn't fire and the response says why:
{ "key": "create_lead", "type": "http", "status": "skipped", "reason": "missing_param", "param": "email" }Where params go
| Type | Params are… |
|---|---|
webhook | sent in the event, under data.params. |
workflow | sent as top-level JSON fields — what n8n, Make and Zapier map directly. |
http | the JSON body of POST, PUT and PATCH requests without a body template, and the query string of GET and DELETE requests whose URL doesn't use them. |
agent | sent in the request body, under params. |
function | passed to your handler as its first argument. |
reply, llm | only used through {{params.…}} in their texts. |
Use params for anything that reaches a third party: a webhook or a workflow never receives the state itself, only the params you map — send what the receiver needs and nothing more.
Templates
Write {{ and }} around a variable — spaces inside are allowed: {{ params.awb }}.
| Variable | Value |
|---|---|
{{params.<name>}} | A param of this destination. |
{{state}}, {{state.<field>}} | The state, or a declared field of an object state. |
{{result.<question>}}, {{confidence.<question>}}, {{scores.<question>}} | An answer, its confidence, a weighted level. |
{{composites.<key>}} | A composite's value. |
{{action}}, {{decision.slug}}, {{decision.version}}, {{execution.id}} | The run. |
{{delivery.id}} | The dlv_… ID of this delivery — the same on every attempt. |
{{secrets.<NAME>}} | A workspace secret. |
The editor's Insert… menu next to each field lists the variables you can use there.
Encoding is automatic
You never escape anything by hand: Dcision encodes each value for the place it goes.
| Where | How values are inserted | Secrets |
|---|---|---|
URLs — webhook.url, http.url, agent.url, workflow.url | URL-encoded. A secret is inserted as-is, so it can hold a whole URL. | Allowed |
Header values — http.headers, agent.headers | As text, with line breaks replaced by spaces — a value can't add a header. | Allowed |
http.body | As JSON — see below. | Allowed |
Texts — reply.text, reply.buttons, llm.instructions, llm.input, agent.instructions | As text, line breaks kept. | Not allowed: the text is returned to the caller or sent to a model. |
As text, strings are inserted as they are, numbers and booleans are printed, objects and arrays become JSON and null becomes an empty string.
JSON bodies
An http body template is JSON with variables, and a variable's place decides how it is written:
- Outside quotes, it becomes a JSON value — a string with its quotes, a number,
true,null, an object. - Inside quotes, it becomes text inside that string, escaped as needed.
For a decision whose object state has email and company_size fields, with a param email taken from state.email:
{
"email": {{params.email}},
"company_size": {{state.company_size}},
"summary": "Route {{result.route}} at {{confidence.route}} — lead score {{composites.lead_score}}",
"lead": {{state}}
}{
"email": "ana@acme.com",
"company_size": 500,
"summary": "Route sales at 0.85 — lead score 0.8414",
"lead": { "message": "We need pricing for 500 users.", "email": "ana@acme.com", "company_size": 500 }
}So write {{state.company_size}} — not "{{state.company_size}}" — to send the number 500 instead of the text "500". {{params.email}} needs no quotes either: its value is a string, so it is written with its quotes.
The body must be valid JSON once the variables are filled in: the editor checks it with sample values when you save, and an invalid template is refused with "The body must be JSON once variables are filled in…". A body is up to 10,000 characters. Leave it empty on POST, PUT and PATCH to send the params as a JSON object; GET and DELETE requests have no body.
Template checks
Templates are validated when you save or deploy:
- every variable must exist:
{{params.awb}}needs a param namedawb,{{state.company_size}}a field of an object state,{{result.route}}a question namedroute; - secret names are UPPER_SNAKE_CASE, such as
{{secrets.CRM_TOKEN}}; - every
{{needs its}}, with one variable inside; - secrets can't be used in texts.
A missing secret isn't a schema error — secrets change without a deploy — but a delivery that references one fails until it is set. See Workspace secrets.
Destination triggers
When a destination fires — conditions on answers, confidence, weighted levels and composites, final actions, a minimum confidence per route, score levels, probability thresholds — and in which order.
Fixed replies
Return a ready-made message — text and optional buttons, with variables — in the API response for a given result, instantly and without calling any model.