What are Custom Variable Types?
A custom variable type is the blueprint for a kind of record your business tracks — a property listing, an insurance policy, a survey question, an account preference set. The type defines the fields each record carries (name, data type, format, allowed values), and every custom variable you create from that type follows the same structure. On the Custom Variables page, each type gets its own tab, and its fields become sortable table columns. Types matter beyond tidy tables: every field of a typed custom variable becomes readable in your call scripts as{{custom.<type_name>.<field_path>}} (typed per your schema — a Text field such as {{custom.property_listing.address}} might read "12 Wattle St, Brisbane QLD 4000"), so a well-designed type is also a well-designed interface between your data and your voice agent.
You manage types from Custom Variables → Custom Variable Types. The dialog opens with two tabs — Installed (your team’s types) and Catalogue (ready-made industry templates) — plus a Create Type button.
Creating a type
Click Create Type to open the type editor. Give the type a name in the Enter type name… field and optionally Add a description… below it.
As you type the name, an internal type identifier is generated from it automatically (lowercase, words joined with underscores — “Property Listing” becomes
property_listing). That identifier is what scripts use in {{custom.property_listing.address}} references, and it is fixed once the type is created — renaming the display name later never changes it, so existing variable references keep working.
Editing an installed type reopens the same editor; you can change the display name, description, validation mode and fields at any time. Deleting a type asks for confirmation and cannot be undone.
Building the field schema
The Fields section lists one row per field, with badges counting the fields you’ve defined and how many are required. Add rows with Add Field (or Add First Field on an empty type), and remove them with the bin icon. Each row has three inline inputs — a Display Label, a path (shown as$.path.to.field) and a type selector — plus a More button that expands the remaining options.
Object fields hold nested structures: expand the row and click Add property to define child fields, each with the same options.
Two other ways to define fields
- Edit JSON — switches the field list to a raw JSON view of the schema for power editing; Field view switches back (invalid JSON must be fixed first).
- Import JSON — paste a sample data record (for example, one item of an API response you plan to send in) and click Generate Fields. Field keys, types and nested objects are inferred automatically, and common formats like email, URL, date and currency are guessed from the key names. Review the generated fields before saving.
How field settings shape data entry
When someone clicks Add Custom Variable and picks your type, the New Custom Variable form is built from the schema: required fields are marked with*, Text fields with allowed values render as dropdowns, Email and URL formats get matching inputs, Number fields carry your minimum/maximum, Yes/No fields are checkboxes, and List/Object fields accept JSON. Field descriptions appear as inline help text.
Validation modes (Off / Warn / Strict)
Each type has a single Validation setting that governs saves of data against it — whether entered in the app, bulk-loaded through a CSV import or submitted through the API.
The checks cover: required fields present (an empty text value counts as missing), values matching their declared type, text length within any minimum/maximum character limits (length limits aren’t in the field builder — set them through the Edit JSON view), Email and URL formats, values within the allowed-values list, and numbers within their minimum/maximum. Fields left empty that aren’t required always pass — validation never demands data you didn’t provide.
Data arriving through the API is held to the core of the same contract under Strict: required fields and matching data types are enforced before anything is stored, and a failed check rejects the request with the reason.
Choosing a mode: start with Off while you’re still shaping the schema, move to Warn once real data flows in (nothing breaks, but drift becomes visible), and switch to Strict when downstream scripts and automations depend on the fields being reliably present and correctly typed.
One record per contact
By default, every custom variable is an independent record — one property listing can link to several contacts, and one contact can hold many listings. Some types work better the other way around: an “account preferences” type should exist exactly once per contact. For that, a type can be configured as unique-by-contact. Instead of creating separate records, data saved against the type is stored directly on the contact, and any new data for the same contact merges into the one record. This option isn’t in the type editor — it’s set when the type is created through the API, and the full storage behaviour is covered in Linking Custom Variables to Contacts. Speak to the Voxworks team for further custom configuration.The type catalogue
The Catalogue tab of the Custom Variable Types dialog lists ready-made types you can adopt without building a schema yourself. Each card shows the type’s name, version, field count, category and industry tags, plus any supported integrations. Click Add to Team to install a copy; installed entries show a tick and read Added. Every catalogue entry is browsable and installable by any team, regardless of your own account’s industry. Installed catalogue types appear on the Installed tab with a Catalogue badge and behave exactly like types you built yourself (own tab, columns, script variables); each arrives with every field at its designed starting value, ready to fill in. Types carrying a Default badge are Voxworks’ recommended starting set for a matching industry — install them from the Catalogue tab the same way as any other entry. The catalogue currently spans two industries: six survey question types for phone research, and four real estate types built around external CRM integrations. For CATI-style phone research, consumed by the Survey tools:
Survey types carry both the question setup you author (question text, options, rotation) and result fields the survey tools write back during calls — for example
{{custom.survey_ro_sc.result}} (Text, e.g. "The Greens"). Leave result fields empty when authoring instances.
For real estate teams, carrying integration tags for Rex, Vault RE, Agentbox and Domain:
Using typed fields in scripts
Every installed type exposes its fields to call scripts, tool inputs and Code Steps under thecustom namespace as {{custom.<type_name>.<field_path>}} — the type identifier plus the field’s path with the leading $. dropped:
{{custom.property_listing.address}}— Text, e.g."12 Wattle St, Brisbane QLD 4000"{{custom.property_listing.price.asking}}— Number (a nested field under an Object), e.g.850000{{custom.survey_ro_sc.question}}— Text, e.g."Which party will you vote for?"
/ in any script field that supports variables to open the picker — installed custom variable types are listed first, and choosing a field inserts the reference for you.
At the start of each call, the agent loads every installed type at its default values, then overlays the data of the custom variables linked to the contact on the call — so which record a script reads is decided by contact linking. Writes from Code Steps persist back to the record immediately.
Next Steps
- Custom Variables Overview — the workspace tour: type tabs, views, add forms and the detail pane.
- Linking Custom Variables to Contacts — how records attach to contacts and reach your scripts at call time.
- Importing Custom Variables from CSV — bulk-load typed records with the
custom.{type}.{field}header convention. - Variables — the full variable reference, including the
customnamespace rules.

