Custom Attributes can be assigned a type of STRING, NUMBER, or DATE. Setting a type does two things:
Unlocks additional comparison operators (greater than, before, etc.) when filtering campaign audiences on that attribute.
Enforces a unique attribute name, so the same name can't be reused with a conflicting type.
In the Workspace UI, Custom Attributes can only be added while editing a pass template via the lightning bolt ⚡ icon on a field, then "+ Custom Attribute" in the Dynamic Fields dropdown. This flow automatically sets the type to STRING.
NUMBER, or DATE types can set via the API. If no type is set it defaults to STRING.
Setting an Attribute's Type
Use the appropriate upsert endpoint for the attribute's scope:
User Attribute (shared across a user's passes) use the
workspaceUserAttributeUpsertendpoint (PUT /v0/workspace/userAttributes).
Pass Attribute (specific to one pass template) use the
passTemplatePassAttributeUpsertendpoint (PUT /v0/passTemplates/{passTemplateId}/passAttributes).
Both endpoints accept an array of attribute objects with a name (required, and must be unique across the workspace for User Attributes, and within the pass template for Pass Attributes), an optional displayName, and an optional type (STRING, NUMBER, or DATE; defaults to STRING).
Example Request: setting a Pass Attribute's type
curl -X PUT "https://api.trybadge.com/v0/passTemplates/PASS_TEMPLATE_ID/passAttributes" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"passAttributes": [
{
"name": "memberBalance",
"displayName": "Member Balance",
"type": "NUMBER"
},
{
"name": "renewalDate",
"displayName": "Renewal Date",
"type": "DATE"
}
]
}'
User Attributes work the same way, with userAttributes in the body. There's no passTemplateId, since User Attributes are shared across all of a user's passes rather than scoped to one template.
⚠️ Type is set once. type is only applied the first time an attribute is created. If you upsert an existing attribute with a different type, the request is rejected with a 400. To change an attribute's type, delete it and recreate it under the same or a new name.
Using Types for Enhanced Filtering in Campaigns
Once an attribute has a NUMBER or DATE type, it unlocks extra comparison operators in the Recipients step of a campaign, beyond a plain exact-match filter.
💡 Multiple filters can be stacked with AND logic, so a typed condition can be combined with other attribute filters to build a precise audience.
NUMBER attributes (e.g. memberBalance) support:
is equal to
is not equal to
is greater than
is less than
DATE attributes (e.g. renewalDate) support:
is before
is after
with a date/time value picker that uses the workspace's configured timezone.
STRING attributes support exact-match filtering only (is equal to / is not equal to).