Help Center / Contacts and CRM /
Smart fields (variables)
Smart fields are variables you insert into proposals, contracts, invoices, receipts, email templates, and automations that replace themselves with real data when the document is viewed or sent. Instead of typing a client's name, address, or invoice amount into every document manually, you insert a variable like client.firstName and Plutio fills in the actual value at render time.
How to insert smart fields
Inside any content block in the block editor, click the Variables button in the editor toolbar (the {x} icon). A dropdown opens showing all available variable categories for that document type. Click a category to expand it, then click the specific field you want to insert. The variable appears in your content as a highlighted tag.
You can also type {{ directly in the editor to trigger the smart field autocomplete. Start typing the field name and select it from the suggestions list.
Smart fields work in content blocks, intro blocks, email template bodies, and automation action fields. They don't work inside image blocks or signature blocks.
When variables are replaced
Variables are replaced at the moment the document is rendered for the viewer. For proposals, contracts, and invoices, the replacement happens when the client opens the document link. For emails, the replacement happens when the email is sent. For PDFs, the replacement happens when the PDF is generated.
If a variable has no data to fill (for example, the client has no phone number), the variable tag stays in the document as-is. You can use conditional logic to hide empty fields entirely (see the Conditional logic section below).
Available variable categories
Which categories appear in the dropdown depends on the document type. A proposal shows proposal, client, workspace, project, and other fields. An invoice shows invoice fields plus client, workspace, and other. The full mapping:
| Document type | Available categories |
|---|---|
| Proposal | Proposal, Client, Workspace, Project, Other |
| Contract | Contract, Client, Workspace, Project, Other |
| Invoice | Invoice, Client, Workspace, Other |
| Subscription | Subscription, Invoice, Client, Workspace, Other |
| Receipt | Receipt, Invoice, Client, Workspace, Other |
| Form | Form, Workspace, Other |
| Email template | Sender, Workspace, Other (plus entity-specific fields depending on the email type) |
| Automation action | All connected entity fields from the automation's trigger and connections |
Workspace fields
Workspace fields pull data from your business settings at Settings > General.
| Variable | What it renders |
|---|---|
| workspace.name | Your workspace/business name |
| workspace.email | Primary business email |
| workspace.emailAlt | Alternative business email |
| workspace.phone | Primary business phone |
| workspace.phoneAlt | Alternative business phone |
| workspace.address | Full formatted address |
| workspace.address.street | Address line only |
| workspace.address.city | City / State |
| workspace.address.zipCode | Post / Zip code |
| workspace.address.country | Country |
| workspace.custom.FIELD_ID | Any workspace custom field |
Client fields
Client fields pull data from the contact or company assigned to the document.
| Variable | What it renders |
|---|---|
| client.name | Full name (first + last) |
| client.firstName | First name |
| client.lastName | Last name |
| client.email | Primary email |
| client.emailAlt | Alternative email |
| client.phone | Primary phone |
| client.phoneAlt | Alternative phone |
| client.address | Full formatted address |
| client.address.street | Address line |
| client.address.city | City / State |
| client.address.zipCode | Post / Zip code |
| client.address.country | Country |
| client.company.name | Company name |
| client.company.email | Company email |
| client.company.phone | Company phone |
| client.company.website | Company website |
| client.company.address | Company full address |
| client.personId | Client's internal ID (useful for links and automations) |
| client.custom.FIELD_ID | Any contact or company custom field |
Proposal fields
Available in proposals and email templates related to proposals.
| Variable | What it renders |
|---|---|
| proposal.name | Proposal title |
| proposal.number | Proposal number (ID) |
| proposal.issueDate | Start / issue date |
| proposal.dueDate | Due / expiry date |
| proposal.signedDate | Date the client signed |
| proposal.amount | Total amount due |
| proposal.link | Client-facing link to the proposal |
| proposal.custom.FIELD_ID | Any proposal custom field |
Invoice fields
Available in invoices, subscriptions, receipts, and related email templates.
| Variable | What it renders |
|---|---|
| invoice.name | Invoice title |
| invoice.number | Invoice number (ID) |
| invoice.ref | Reference / PO number |
| invoice.issueDate | Issue date |
| invoice.dueDate | Payment due date |
| invoice.paidDate | Date paid |
| invoice.amount | Total amount due |
| invoice.agreement | Invoice type (e.g. standard, split) |
| invoice.link | Client-facing link to the invoice |
| invoice.custom.FIELD_ID | Any invoice custom field |
Contract fields
| Variable | What it renders |
|---|---|
| contract.name | Contract title |
| contract.number | Contract number (ID) |
| contract.signedDate | Date signed (shows each signer and date for multi-signee contracts) |
| contract.link | Client-facing link to the contract |
| contract.custom.FIELD_ID | Any contract custom field |
Project fields
Available in proposals, contracts, and any document linked to a project.
| Variable | What it renders |
|---|---|
| project.name | Project name |
| project.startDate | Project start date |
| project.dueDate | Project due date |
| project.custom.FIELD_ID | Any project custom field |
Subscription fields
Available in subscription documents and related emails.
| Variable | What it renders |
|---|---|
| invoiceSubscription.title | Subscription title |
| invoiceSubscription.amount | Recurring amount |
| invoiceSubscription.type | Billing type (manual or auto) |
| invoiceSubscription.paymentOptions | Payment method |
| invoiceSubscription.startDate | Subscription start date |
| invoiceSubscription.endDate | Subscription end date |
| invoiceSubscription.upcomingInvoiceDate | Next invoice date |
| invoiceSubscription.custom.FIELD_ID | Any subscription custom field |
Receipt fields
Available in receipt documents.
| Variable | What it renders |
|---|---|
| receipt.receiptNumber | Receipt number |
| receipt.paymentMethod | Payment method used |
| receipt.paidDate | Date paid |
| receipt.amount | Amount paid |
| receipt.link | Client-facing link to the receipt |
Task fields
Available in automation actions and email templates triggered by task events.
| Variable | What it renders |
|---|---|
| task.title | Task title |
| task.description | Task description |
| task.status | Current status |
| task.dueDate | Due date |
| task.startDate | Start date |
| task.completedAt | Date completed |
| task.assignedTo | Assigned to (name) |
| task.createdBy | Assigned by / created by |
| task.followers | Follower names (comma-separated) |
| task.project | Project name |
| task.taskBoard | Task board name |
| task.taskGroup | Task group (column) name |
| task.assigneeIds | Assignee IDs (for automations targeting recipients) |
| task.custom.FIELD_ID | Any task custom field |
Form fields
Available in form confirmation pages, related emails, and automations triggered by form submissions.
| Variable | What it renders |
|---|---|
| form.title | Form title |
| form.submitter | Name of the person who submitted |
| form.submitterPersonId | Submitter's internal ID |
| form.response | Full form response (all answers) |
| form.custom.FIELD_ID | Any form custom field |
In automations, if the trigger is a form submission and a specific form is selected, individual form question responses also become available as variables. Each question appears as a separate field you can insert.
Sender and person fields
Sender fields represent the person sending the document or email. Person fields represent a contact record directly. Both share the same structure.
| Variable | What it renders |
|---|---|
| sender.firstName / person.firstName | First name |
| sender.lastName / person.lastName | Last name |
| sender.fullName / person.fullName | Full name |
| sender.email / person.email | Primary email |
| sender.emailAlt | Alternative email |
| sender.phone / person.phone | Primary phone |
| sender.phoneAlt | Alternative phone |
| sender.address | Full address |
| sender.role / person.role | Role in workspace |
| sender.timezone / person.timezone | Timezone |
| sender.company.name | Sender's company name |
| sender.avatar.url | Avatar image URL (for email signatures) |
Organizer fields
Available in scheduler booking confirmations and related emails. The organizer is the team member who owns the booking page.
| Variable | What it renders |
|---|---|
| organizer.firstName | First name |
| organizer.lastName | Last name |
| organizer.fullName | Full name |
| organizer.email | |
| organizer.phone | Phone |
Other fields
| Variable | What it renders |
|---|---|
| other.dateNow | Today's date at the time the document is rendered |
The Invite category is used internally for invitation emails:
| Variable | What it renders |
|---|---|
| invite.link | The invitation link for the recipient to join the workspace |
Custom fields as variables
Every custom field you create on any record type automatically becomes available as a smart field variable. Custom field variables follow the pattern entity.custom.FIELD_ID, where FIELD_ID is the internal identifier of the custom field.
You don't need to know the field ID. When you click Variables in the toolbar, your custom fields appear by name at the bottom of each category. Click a custom field name and the correct variable is inserted automatically.
Custom fields from contacts and companies are available under the Client category. Custom fields from projects appear under Project. Custom fields from proposals, invoices, contracts, and other entities appear under their respective categories.
Conditional logic
Smart fields support #if and #unless blocks that show or hide content based on whether a field has a value.
Show content only when a field has a value:
#if invoice.refReference: invoice.ref/ifIf the invoice has no reference number, the entire line disappears from the rendered document, including the "Reference:" label. Plutio also cleans up stray <br> tags left behind by empty conditionals, so you won't end up with blank lines in the output.
Show content only when a field is empty:
#unless invoice.paidDatePayment pending/unlessThe text "Payment pending" only appears if the invoice hasn't been paid yet.
If/else for two-way logic:
#if project.nameProject: project.nameelseNo project assigned/ifShows the project name if one exists, otherwise shows "No project assigned".
Unless/else:
#unless invoice.paidDateAwaiting paymentelsePaid on invoice.paidDate/unlessYou can use conditionals inside any content block. They're especially useful in templates where some fields might be filled for one client but empty for another. A common pattern is wrapping optional fields in #if blocks so the document adapts automatically:
Invoice number: invoice.number Issue date: invoice.issueDate Due date: invoice.dueDate #if invoice.paidDatePayment date: invoice.paidDate/if #if invoice.refReference: invoice.ref/if #if project.nameProject: project.name/ifOnly the fields with values render. Empty ones are removed along with their labels and any trailing line breaks.
Looping with each
The #each block iterates over arrays. When a smart field resolves to a list of values (like task assignees), #each lets you render each item individually.
Most list-type fields like task.followers and task.assignedTo resolve to a pre-joined comma-separated string, so you can insert them directly without #each. For example, task.followers renders as "Sarah, James, Alex".
Address fields
Address variables have two modes. The client.address variable (without a sub-field) renders the full formatted address as a single block of text. The sub-fields (client.address.street, client.address.city, client.address.zipCode, client.address.country) render individual address parts.
You can use both in the same document. For example, the full address in one place and just the city in another. The same pattern applies to workspace.address, sender.address, and client.company.address.
Smart fields in automations
In automations, smart fields pull data from the trigger entity and any connected entities in the automation flow. If an automation is triggered by a form submission and creates an invoice, the automation's email action can reference both form variables (form1.title, form1.submitter) and invoice variables (invoice1.number, invoice1.amount).
Connection variables use a numbered suffix to distinguish between multiple connections of the same type: invoice1.number for the first invoice, invoice2.number if there are two. Each connection's available fields appear in the smart field picker when configuring the automation action.
Automation smart fields also include cross-entity references like invoice1.client.name to get the client assigned to a specific connected invoice.
What happens with empty variables
If a variable references a field that has no data, it stays in the document as the raw variable text (for example, client.phone appears literally). To avoid this, wrap optional fields in #if blocks so they disappear cleanly when empty.
The most common reasons a variable renders empty or as raw text:
- No client assigned - the document doesn't have a contact linked to it yet, so all client fields are empty.
- Missing data on the contact - the contact exists but the specific field (phone, address, company) hasn't been filled in.
- Wrong entity context - using a proposal variable inside an invoice that isn't linked to a proposal.
- Custom field deleted - the custom field was removed from settings, so the variable can't resolve.
To fix it, make sure the document has a client assigned, then check that the client's record in Contacts has the field filled in.
Tips and best practices
- Use conditionals in templates - wrap every optional field in #if blocks when building templates. The document adapts to each client's data without leaving blank lines or raw variable text.
- Full address vs parts - use client.address for a single-line formatted address. Use the individual parts (.street, .city, .zipCode, .country) when you need to control the layout, like placing city and postal code on separate lines.
- Test with a real contact - before sending, preview the document with the actual client assigned. The preview renders all smart fields with real data so you can spot blanks or formatting issues.
- Today's date - use other.dateNow for documents that need the current date at render time. The date updates every time the document is opened.
- Email signatures - use sender.avatar.url for the sender's profile image and sender.fullName for their name in email signatures. Each team member's emails pull from their own profile data automatically.