English
English
English
English
Every value you reference in a spec — a field on the source model, an enrichment, a constant, the result of an earlier upsert — has a type (string, number, datetime, agent identity, …). The Spec Builder uses those types to autocomplete what's available where you're typing, and to warn you when you're about to wire something that doesn't fit. This page is the reference for what types exist, where variables come from, and what the type system protects you from.
In a fresh spec, four things put variables in scope:
var you set on the source model in the spec config; the default name is whatever the source model's identifier suggests, like event for ghl_opportunity_stage_change or dossier for cube.return_as — every operation that captures a result (upsert_*, define_variable, lock_record_field, insert_contact_period_change) adds a variable in scope from that point forward. Whatever name you set in return_as is what the rest of the spec uses to reference it.for_each — when the cursor is inside the body of a for_each block, the current item is in scope under whatever name you typed for item_var (e.g. field, line, membership). It disappears once the loop ends.The Spec Builder's scope panel shows you exactly what's available at the currently selected step. Variable pickers and expression-builder fields autocomplete from that same scope.
Every variable and every expression has a type. Here's the full set, grouped by what they're for:
string — plain text. Most source fields land here.number — integers and decimals. Used for amounts, durations, IDs that happen to be numeric.boolean — true or false. The result of every condition expression (equals, is_empty, and, …).datetime — a fully-parsed point in time. Source fields almost never start as datetime — they're strings or timestamps until you wrap them with parse_datetime or parse_timestamp.object — a nested record with named child fields. An enrichment becomes an object on the source model (e.g. event.ghl_opportunity is an object with id, name, status, …).array — a list of items. Used for things like a contact's custom fields or an order's line items. Iterate over it with for_each.These are what upsert_*_external_identity operations hand back when you set return_as. Operations like upsert_activity and upsert_sale expect these types in their identity fields, not plain strings — so you almost always capture an identity with return_as and then pass the captured variable along.
agent_external_identityteam_external_identityproject_external_identitysegment_external_identityproposition_external_identityrecord — what data-upsert operations and define_variable hand back. The result of an upsert_activity is a record, captured with return_as and passed to lock_record_field or read for fields like activity.contact_key.Two places where the type system actively helps you:
Autocomplete. When you click into a variable picker or an expression-builder field, the dropdown only suggests variables whose type fits what the field expects. Pickers for an agent_external_identity field won't surface plain string variables; pickers for a datetime field won't surface unparsed string fields.
Type warnings on save. When you save a spec, the validator checks that every wiring is compatible: that the expression you put into a datetime field actually returns a datetime, that the variable in an agent_external_identity slot is in fact an agent identity, and so on. Mismatches block the save and surface inline so you can see exactly which step is wrong.
You can usually convert between types with an expression where conversion is well-defined: a string that looks like a timestamp goes through parse_timestamp to become a datetime; a record from upsert_activity exposes its fields by path access (activity.contact_key is a string).
Some fields on source models are marked as containing end-customer personal data — a contact's name, email, phone, gender. SalesDash doesn't store those values in any record it writes, and the validator blocks any spec that tries to reference them: in expressions, in operation fields, anywhere.
The variable picker shows these fields greyed out and doesn't let you select them. If you do reference one (e.g. by typing the path manually), the spec fails to save with a clear error pointing at the offending field.
This isn't a configurable rule — it's enforced by the source model's field schema, declared by SalesDash. The aim is that no end-customer personally-identifiable information ever ends up inside SalesDash, even by accident, regardless of how a spec is wired.
If you find a source model exposing a field that should be marked as personal data and isn't, flag it to support — that's a schema correction, not a spec change.