Contact Properties
Relevant source files
The following files were used as context for generating this wiki page:
Contact properties define the schema for custom data stored on individual contacts. They function as column definitions, allowing you to create specific property keys (e.g., company_name) and assign values to those keys for specific contacts.
Sources: src/commands/contact-properties/index.ts:13-16
Architecture and Data Flow
The system manages property definitions separately from property values. You first define a property with a specific key and type. Once defined, you set values for these properties when creating or updating contacts.
Property Lifecycle
The following diagram illustrates the flow from property definition to its use in email templates.
The diagram shows how property definitions move from administrative setup to individual contact application and final interpolation.
Sources: src/commands/contact-properties/index.ts:13-20, src/commands/contacts/create.ts:101-104
Property Definitions
A property definition consists of a key, a data type, and an optional fallback value. The key and type become immutable after creation.
Supported Data Types
| Type | Description | Usage |
|---|---|---|
string | Textual data | Default for text values like company names or departments. |
number | Numeric data | Used for counts, scores, or thresholds. |
Sources: src/commands/contact-properties/index.ts:25-27, src/commands/contact-properties/create.ts:17-21
Reserved Keys
Certain keys are built-in and cannot be created as custom properties:
FIRST_NAMELAST_NAMEEMAILUNSUBSCRIBE_URL
Sources: src/commands/contact-properties/index.ts:23, src/commands/contact-properties/create.ts:40
Command Implementation
The CLI provides five primary subcommands for managing contact property definitions through the resend contact-properties command group.
The class diagram represents the logical operations available within the contact-properties module.
Sources: src/commands/contact-properties/index.ts:45-50, src/commands/contact-properties/create.ts:108-112
Creation Logic
When creating a property, the CLI validates the inputs:
- Key Requirement: You must provide a key name.
- Type Requirement: You must select either
stringornumber. - Number Coercion: If the type is
number, the CLI parses thefallback-valueinto a float.
Sources: src/commands/contact-properties/create.ts:86-106
Update Restrictions
Only the fallback-value is updatable. The CLI prevents updates to the key or type because changing these would break existing broadcast templates that reference the original key.
Sources: src/commands/contact-properties/update.ts:25-33
Template Interpolation
Property values are interpolated into broadcasts using triple-brace syntax. The system follows a specific priority for determining which value to render.
Interpolation Logic Flow
The flow shows the hierarchy of values used during email rendering.
Sources: src/commands/contact-properties/index.ts:18-21, src/commands/contact-properties/update.ts:31-33
Syntax Examples
| Syntax | Result |
|---|---|
{{{company_name}}} | Renders the contact's company or the property's stored fallback. |
{{{company_name|Unknown}}} | Renders "Unknown" if no value is set for the contact. |
Sources: src/commands/contact-properties/index.ts:19-21, src/commands/contact-properties/create.ts:37-38
Contact Integration
You set property values on contacts by passing a JSON object to the --properties flag when running contact commands.
// Example of how properties are parsed from JSON strings
export function parsePropertiesJson(
raw: string | undefined,
globalOpts: GlobalOpts,
): Record<string, string | number | null> | undefined {
if (!raw) return undefined;
try {
return JSON.parse(raw) as Record<string, string | number | null>;
} catch {
outputError({ message: 'Invalid --properties JSON.', code: 'invalid_properties' }, { json: globalOpts.json });
}
}
Sources: src/commands/contacts/utils.ts:87-100
Contact properties provide a flexible way to extend the contact data model. By defining clear schemas with types and fallbacks, you ensure that personalized email content remains consistent even when specific contact data is missing.