Skip to content

Pass Templates

Pass templates define the design and structure of wallet passes — colors, fields, images, and barcode configuration applied to every pass created from them.

All template CRUD endpoints are dedicated /wallethero-api/... endpoints

Earlier SDK versions hit Directus-native /items/pass_templates. They no longer do. Every method on wh.passTemplates now calls a dedicated, workspace-scoped wallethero-api endpoint guarded by createWorkspaceGuard. Image handling is the exception: it uploads through the Directus-native POST /files endpoint and then PATCHes the returned file IDs onto the template (see Template Images).

Auth: Bearer token — caller must be a member of the workspace. List/create routes derive the workspace from the path; get/update/delete routes load the template row and check membership against its workspace_id.

List Pass Templates

GET /wallethero-api/workspace/:workspaceId/pass-templates

Lists all templates in a workspace, newest first. Cross-workspace listing is not supported — the SDK throws if filter.workspace_id._eq is missing.

Auth: Bearer token — workspace member.

Path Parameters

ParameterTypeDescription
workspaceIdstring (UUID)Workspace identifier

Example Request

bash
curl "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/pass-templates" \
  -H "Authorization: Bearer YOUR_TOKEN"

SDK

typescript
const templates = await wh.passTemplates.list({
  filter: { workspace_id: { _eq: "WORKSPACE_ID" } },
});
// Convenience wrappers:
await wh.passTemplates.getByWorkspace("WORKSPACE_ID");
await wh.passTemplates.getByProject("PROJECT_ID");   // GET /wallethero-api/projects/:id/templates
await wh.passTemplates.search("gold", { filter: { workspace_id: { _eq: "WORKSPACE_ID" } } });

Get Pass Template

GET /wallethero-api/pass-templates/:id

Fetches a single template by UUID.

Auth: Bearer token — member of the template's workspace.

Path Parameters

ParameterTypeDescription
idstring (UUID)Template identifier

Example Request

bash
curl "https://api.wallethero.app/wallethero-api/pass-templates/TEMPLATE_ID" \
  -H "Authorization: Bearer YOUR_TOKEN"

SDK

typescript
const template = await wh.passTemplates.get("TEMPLATE_ID");

Create Pass Template

POST /wallethero-api/workspace/:workspaceId/pass-templates

Creates a template. See Create Pass Template for the full request body.

SDK

typescript
const template = await wh.passTemplates.create({
  name: "Gold Member Card",
  workspace_id: "WORKSPACE_ID",
  project_id: "PROJECT_ID",
  apple_pass_type_identifier: "pass.com.example.loyalty",
  pass_type: "LOYALTY",
});

Update Pass Template

PATCH /wallethero-api/pass-templates/:id

Updates a template. See Update Pass Template.

SDK

typescript
await wh.passTemplates.update("TEMPLATE_ID", { background_color: "#2d2d44" });

Delete Pass Template

DELETE /wallethero-api/pass-templates/:id

Deletes a template. To delete a template that still has passes, migrate them first (see below).

Auth: Bearer token — member of the template's workspace.

Path Parameters

ParameterTypeDescription
idstring (UUID)Template identifier

Example Request

bash
curl -X DELETE "https://api.wallethero.app/wallethero-api/pass-templates/TEMPLATE_ID" \
  -H "Authorization: Bearer YOUR_TOKEN"

Response (200)

json
{ "message": "pass_templates deleted" }

SDK

typescript
await wh.passTemplates.delete("TEMPLATE_ID");

Migrate Passes and Delete Template

POST /wallethero-api/templates/:templateId/migrate-and-delete

Moves every pass from the source template to a target template (in the same workspace), then deletes the source. Use this to retire a template that still has active passes.

Auth: Bearer token — member of the source template's workspace. The target template must belong to the same workspace.

Path Parameters

ParameterTypeDescription
templateIdstring (UUID)Source template to delete

Request Body

FieldTypeRequiredDescription
target_template_idstring (UUID)YesTemplate to move the passes to. Must differ from templateId and share the workspace

Example Request

bash
curl -X POST "https://api.wallethero.app/wallethero-api/templates/SOURCE_TEMPLATE_ID/migrate-and-delete" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "target_template_id": "TARGET_TEMPLATE_ID" }'

Response (200)

json
{
  "data": {
    "deleted_template_id": "source-template-uuid",
    "target_template_id": "target-template-uuid",
    "migrated_passes": 128
  }
}

SDK

typescript
const result = await wh.passTemplates.migrateAndDelete(
  "SOURCE_TEMPLATE_ID",
  "TARGET_TEMPLATE_ID",
);

Template Structure

typescript
interface PassTemplate {
  id: string;
  uuid: string;
  name: string;
  description?: string;
  pass_type: "LOYALTY" | "GIFT_CARD" | "EVENT_TICKET" | "OFFER" | "GENERIC";
  apple_pass_type_identifier: string;
  workspace_id: string;
  project_id: string;

  // Visual design
  background_color?: string;   // Hex, e.g. "#FF5733"
  label_color?: string;
  value_color?: string;
  logo_text?: string;

  // Images (Directus file IDs)
  icon?: string;
  logo?: string;
  cover_image?: string;

  // Barcode
  barcode_type?: "none" | "qr" | "aztec" | "code128" | "pdf417";
  barcode_id?: string;
  barcode_label?: string;

  // Fields
  top_field_label?: string;
  top_field_value?: string;
  front_fields?: PassField[];
  secondary_fields?: PassField[];
  back_fields?: PassField[];

  // Back-of-pass loyalty sections
  show_benefits_on_back?: boolean;
  show_available_rewards_on_back?: boolean;
  show_active_rewards_on_back?: boolean;
  show_loyalty_portal_link_on_back?: boolean;
  show_referral_code_on_back?: boolean;
  back_sections_order?: BackSectionRef[] | null;

  // Location & deeplink
  locations?: Location[];
  location_message?: string;
  ios_deeplink_id?: number;
  ios_deeplink_url?: string;

  // Tier (loyalty)
  tier_id?: string;
  tier_label?: string;

  // Read-only
  statistics?: PassTemplateStatistics;
}

interface PassField {
  id?: string;
  label: string;
  value: string;  // Supports {{field}} interpolation
}

interface Location {
  latitude: number;
  longitude: number;
  altitude?: number;
  name?: string;
}

Field Interpolation

Field values support interpolation, resolved from the related client's identity and custom fields:

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

Available variables include the client's identity fields (, , ) and any custom field defined on the client — see Pass Custom Fields.

WalletHero Documentation