Skip to content

Pass Custom Fields

Custom fields are arbitrary key/value data used to personalize passes and drive segmentation. They are stored on the client (clients.custom_fields), not on the pass — every pass reads them from its related client.

Where things live

  • Reading/writing values for a specific client: use the Clients endpoints (wh.clients.updateCustomFields(...)).
  • Defining the field schema for a workspace: use the workspace data model (wh.workspaces.createDataModelField(...)).
  • Discovering which fields and values are in use: the two dedicated discovery endpoints documented below.

Discover Custom Field Names

GET /wallethero-api/passes/custom-fields?workspace_id=:workspaceId

Returns the list of non-system custom field names defined in the workspace data model, ordered by their configured sort order.

Auth: Bearer token — member of the workspace (membership is derived from the workspace_id query parameter).

Query Parameters

ParameterTypeRequiredDescription
workspace_idstring (UUID)YesWorkspace identifier

Example Request

bash
curl "https://api.wallethero.app/wallethero-api/passes/custom-fields?workspace_id=WORKSPACE_ID" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response (200)

json
{ "data": ["tier", "points", "member_since", "store_preference"] }

SDK

typescript
const fieldNames = await wh.segments.getCustomFieldNames("WORKSPACE_ID");
// => ["tier", "points", "member_since", "store_preference"]

Discover Custom Field Values

GET /wallethero-api/passes/custom-fields/:fieldName/values?workspace_id=:workspaceId&limit=:limit

Returns the distinct values stored for a single custom field across the workspace's clients, with occurrence counts and a isNumeric flag. Useful for building dynamic segment filters.

Auth: Bearer token — member of the workspace (derived from the workspace_id query parameter).

Path Parameters

ParameterTypeDescription
fieldNamestringCustom field name. Must match ^[a-zA-Z_][a-zA-Z0-9_]*$

Query Parameters

ParameterTypeRequiredDefaultDescription
workspace_idstring (UUID)YesWorkspace identifier
limitnumberNo50Max distinct values to return (capped at 100)

Example Request

bash
curl "https://api.wallethero.app/wallethero-api/passes/custom-fields/tier/values?workspace_id=WORKSPACE_ID&limit=50" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response (200)

json
{
  "data": [
    { "value": "Gold", "count": 412, "isNumeric": false },
    { "value": "Silver", "count": 890, "isNumeric": false },
    { "value": "Bronze", "count": 1503, "isNumeric": false }
  ]
}

SDK

typescript
const values = await wh.segments.getCustomFieldValues("WORKSPACE_ID", "tier", 50);
// => [{ value: "Gold", count: 412, isNumeric: false }, ...]

Supported Data Types

TypeDescriptionExample
stringText value"Gold", "[email protected]"
numberInteger or decimal1500, 99.99
booleanTrue/falsetrue, false
dateISO date string"2024-01-15"
arrayArray of strings (multiselect)["sports", "music"]

Setting Custom Fields

Custom fields are written on the client. They propagate to every pass that client holds.

typescript
// On pass creation, via client_identity (auto-create/reuse the client)
await wh.passes.create({
  pass_template_id: "TEMPLATE_ID",
  project_id: "PROJECT_ID",
  workspace_id: "WORKSPACE_ID",
  client_identity: {
    email: "[email protected]",
    custom_fields: { points: 0, tier: "Bronze", member_since: "2024-01-15" },
  },
});

// Later, update (merged with existing values)
await wh.clients.updateCustomFields("WORKSPACE_ID", "CLIENT_ID", {
  points: 1500,
  last_purchase: "2024-01-15",
});

// Remove a field by setting it to null
await wh.clients.updateCustomFields("WORKSPACE_ID", "CLIENT_ID", {
  temporary_promo: null,
});

Displaying Custom Fields

Reference field values in pass template field definitions:

json
{
  "front_fields": [
    { "label": "Member", "value": "{{first_name}} {{last_name}}" },
    { "label": "Points", "value": "{{points}}" },
    { "label": "Status", "value": "{{tier}}" }
  ]
}

Defining a Data Model

For consistent fields (and to make them appear in getCustomFieldNames), define them on the workspace data model:

typescript
await wh.workspaces.createDataModelField("WORKSPACE_ID", {
  field_name: "tier",
  field_label: "Membership Tier",
  field_type: "string",
  default_value: "Bronze",
  allowed_values: ["Bronze", "Silver", "Gold", "Platinum"],
});

Best Practices

  1. Use consistent field names across all clients in a workspace.
  2. Define a data model so fields show up in discovery endpoints and validation runs.
  3. Use appropriate types — numbers for numeric values, not strings.
  4. Keep structure flat — avoid deeply nested objects.
  5. Choose filterable names — discovery endpoints and segment filters key off the field name.

WalletHero Documentation