Skip to content

Create Pass

Create a new wallet pass and link it to a client.

POST /wallethero-api/workspace/:workspaceId/passes

Dedicated wallethero-api endpoint

This is a workspace-scoped wallethero-api endpoint, not Directus /items/passes. The workspace_id is taken from the path and set on the created row server-side.

Identity (first_name, last_name, email, phone, marketing_consent) and custom_fields live on the client, not the pass. Either pass an existing client_id, or pass client_identity to auto-create/reuse a client by (workspace_id, email).

Authentication

Bearer token — caller must be a member of the workspace in the path.

Path Parameters

ParameterTypeDescription
workspaceIdstring (UUID)Workspace identifier

Request Body

FieldTypeRequiredDefaultDescription
pass_template_idstring (UUID)YesTemplate identifier
project_idstring (UUID)YesProject identifier
workspace_idstring (UUID)YesWorkspace identifier (must match the path)
client_idstring (UUID)NonullExisting client to link. Identity and custom fields are read from this client
client_identityobjectNoProvide instead of client_id to auto-create/reuse a client by (workspace_id, email)
notificationstringNonullInitial push notification message
metadataobjectNoArbitrary metadata stored with the request
enroll_loyalty_programbooleanNotrueEnroll the resolved client in the loyalty program. An already-enrolled client keeps their original enrollment date

client_identity Object

FieldTypeRequiredDescription
emailstringYesClient email — used to look up or create the client
first_namestringNoClient first name
last_namestringNoClient last name
phonestringNoClient phone
marketing_consentbooleanNoMarketing consent flag
sourcestringNoAcquisition source label
custom_fieldsobjectNoWorkspace data-model custom fields applied to the client (routed through updateClientFields so field-change events fire)

Example Request

bash
curl -X POST "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/passes" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pass_template_id": "TEMPLATE_ID",
    "project_id": "PROJECT_ID",
    "workspace_id": "WORKSPACE_ID",
    "client_id": "CLIENT_ID"
  }'

Auto-create the client by identity instead of passing client_id:

bash
curl -X POST "https://api.wallethero.app/wallethero-api/workspace/WORKSPACE_ID/passes" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pass_template_id": "TEMPLATE_ID",
    "project_id": "PROJECT_ID",
    "workspace_id": "WORKSPACE_ID",
    "client_identity": {
      "email": "[email protected]",
      "first_name": "John",
      "last_name": "Doe",
      "custom_fields": { "tier": "Bronze", "points": 0 }
    }
  }'

Response (201)

json
{
  "data": {
    "id": "pass-uuid",
    "pass_template_id": "template-uuid",
    "project_id": "project-uuid",
    "workspace_id": "workspace-uuid",
    "client_id": "client-uuid",
    "apple_pass_url": "https://api.wallethero.app/...",
    "apple_qrcode_url": "https://api.wallethero.app/...",
    "google_pass_url": "https://pay.google.com/gp/v/save/...",
    "google_qrcode_url": "https://api.wallethero.app/...",
    "date_created": "2024-01-15T10:30:00Z"
  }
}

Response Fields

FieldTypeDescription
idstring (UUID)Unique pass identifier
pass_template_idstring (UUID)Template used for this pass
project_idstring (UUID)Project this pass belongs to
workspace_idstring (UUID)Workspace this pass belongs to
client_idstring (UUID)Linked client identifier
notificationstringLast notification sent
pass_fieldsobjectPass-display overrides
barcode_valuestringPre-interpolated barcode value
apple_pass_urlstring (URL)Direct download URL for Apple Wallet pass
apple_qrcode_urlstring (URL)QR code URL for Apple Wallet pass
google_pass_urlstring (URL)Google Wallet save URL
google_qrcode_urlstring (URL)QR code URL for Google Wallet pass
date_createdstring (ISO 8601)Creation timestamp

To return the linked client inline (identity + custom_fields), expand the relation:

GET /wallethero-api/passes/{pass_id}?fields=*,client.*

SDK Example

typescript
// Link an existing client
const pass = await wh.passes.create({
  pass_template_id: "TEMPLATE_ID",
  project_id: "PROJECT_ID",
  workspace_id: "WORKSPACE_ID",
  client_id: "CLIENT_ID",
});

console.log("Apple Pass URL:", pass.data.apple_pass_url);
console.log("Google Wallet URL:", pass.data.google_pass_url);
typescript
// Auto-create the client by identity
const pass = await wh.passes.create({
  pass_template_id: "TEMPLATE_ID",
  project_id: "PROJECT_ID",
  workspace_id: "WORKSPACE_ID",
  client_identity: {
    email: "[email protected]",
    first_name: "John",
    last_name: "Doe",
    custom_fields: { tier: "Bronze", points: 0 },
  },
});

Bulk Create

bulkCreateFromTemplate issues one create call per pass (each scoped to its own workspace):

typescript
const result = await wh.passes.bulkCreateFromTemplate("TEMPLATE_ID", [
  { workspace_id: "WORKSPACE_ID", project_id: "PROJECT_ID", client_id: "CLIENT_A" },
  { workspace_id: "WORKSPACE_ID", project_id: "PROJECT_ID", client_id: "CLIENT_B" },
]);

Sending the Pass to Users

After creating a pass, you can:

  1. Direct Download: Send the apple_pass_url to the user.
  2. QR Code: Display apple_qrcode_url or google_qrcode_url for scanning.
  3. Email: Re-send via wh.passes.resendEmail(passId) (POST /wallethero-api/pass/resend), or use distributions to collect and email passes.
typescript
await wh.passes.resendEmail(pass.data.id);

Errors

StatusCodeDescription
400INVALID_PAYLOADMissing required fields
403FORBIDDENCaller is not a member of the workspace
404RECORD_NOT_FOUNDTemplate, project, or workspace not found

WalletHero Documentation