stemp Logostemp Developer

Users & Wallet Passes

Create and manage users and issue wallet passes via the stemp API.

Users & Wallet Passes

Users and wallet passes are the core resources of the stemp platform. Users represent your customers, and wallet passes are the digital cards they add to Apple Wallet or Google Wallet.

Users

Create a User

curl -X POST https://api.stemp.app/api/v1/users \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "name": "Jane Doe",
    "phone": "+491701234567",
    "externalId": "cust_123"
  }'

Required scope: user:create

FieldRequiredDescription
emailYesValid email address (max 254 characters)
nameNoFull name (max 150 characters)
phoneNoPhone number (max 20 characters)
externalIdNoYour system's customer ID (max 100 characters)
metadataNoCustom key-value metadata

Response:

{
  "id": "usr_xyz789",
  "object": "user",
  "email": "jane@example.com",
  "name": "Jane Doe",
  "phone": "+491701234567",
  "externalId": "cust_123",
  "metadata": {},
  "createdAt": "2026-01-15T10:30:00Z",
  "updatedAt": "2026-01-15T10:30:00Z"
}

Get a User

Retrieve a user by their stemp ID or your external ID:

# By stemp ID
curl https://api.stemp.app/api/v1/users/usr_xyz789 \
  -H "Authorization: Bearer <token>"

# By external ID
curl https://api.stemp.app/api/v1/users/cust_123 \
  -H "Authorization: Bearer <token>"

Required scope: user:read

List Contacts

Use GET /v1/contacts to list the end-customers (contacts) of your organization. The endpoint is paginated and supports server-side search and stamp-card filtering.

curl "https://api.stemp.app/api/v1/contacts?page=0&size=50" \
  -H "Authorization: Bearer <token>"

Required scope: user:read

Query parameters:

ParameterTypeDescription
pageintZero-based page number. Default 0.
sizeintPage size. Default 50, capped at 200.
sortstringSort expression (e.g. createdAt,desc). Defaults to createdAt,desc.
searchstringCase-insensitive substring match across email, name, phone, and externalId.
templateIdstringRestrict to contacts who own a wallet pass for this stamp-card template.
minStampsintInclusive lower bound on the current stamp count. Requires templateId.
maxStampsintInclusive upper bound on the current stamp count. Requires templateId.
includeStampsboolWhen true, embed per-pass stamp progress on each contact. Automatically enabled when a stamp filter is active. Default false.

Search example:

curl "https://api.stemp.app/api/v1/contacts?search=jane" \
  -H "Authorization: Bearer <token>"

Stamp-card filter example — all contacts with 5 out of 10 stamps on a given template:

curl "https://api.stemp.app/api/v1/contacts?templateId=tpl_abc123&minStamps=5&maxStamps=5" \
  -H "Authorization: Bearer <token>"

The response is a Spring-style page object:

{
  "content": [
    {
      "id": "usr_xyz789",
      "object": "contact",
      "email": "jane@example.com",
      "name": "Jane Doe",
      "phone": "+491701234567",
      "externalId": "cust_123",
      "passInfos": [
        { "templateId": "tpl_abc123", "passId": "wp_abc456" }
      ],
      "stampProgress": [
        { "templateId": "tpl_abc123", "passId": "wp_abc456", "currentStamps": 5, "maxStamps": 10, "timesCompleted": 0 }
      ],
      "createdAt": "2026-01-15T10:30:00Z",
      "updatedAt": "2026-01-15T10:30:00Z"
    }
  ],
  "totalElements": 42,
  "totalPages": 1,
  "number": 0,
  "size": 50
}

stampProgress is only present when includeStamps=true or when a stamp filter is active.

List Users (deprecated)

Deprecated: Use GET /v1/contacts instead. The legacy endpoint returns all users of the organization in a single unpaginated list and does not support server-side search or stamp-card filtering. It will be removed in a future version.

curl "https://api.stemp.app/api/v1/users" \
  -H "Authorization: Bearer <token>"

Required scope: user:read

Update a User

Use PATCH to update specific fields:

curl -X PATCH https://api.stemp.app/api/v1/users/usr_xyz789 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Jane Smith",
    "phone": "+491709876543"
  }'

Required scope: user:update

Delete a User

curl -X DELETE https://api.stemp.app/api/v1/users/usr_xyz789 \
  -H "Authorization: Bearer <token>"

Required scope: user:update

Warning: Deleting a user revokes all their wallet passes.

List User's Passes

curl https://api.stemp.app/api/v1/users/usr_xyz789/passes \
  -H "Authorization: Bearer <token>"

Required scope: pass:read

The response includes each pass with its template info, installation status, and stamp state.


Wallet Passes

Wallet passes are digital cards tied to a template (design) and a user. Each pass has a unique QR code and can be added to Apple Wallet or Google Wallet.

Create a Wallet Pass

You can create a pass for an existing user or create a new user inline:

For an existing user:

curl -X POST https://api.stemp.app/api/v1/templates/{templateId}/walletpasses \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "usr_xyz789"
  }'

With inline user creation:

curl -X POST https://api.stemp.app/api/v1/templates/{templateId}/walletpasses \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "user": {
      "email": "jane@example.com",
      "name": "Jane Doe",
      "externalId": "cust_123"
    }
  }'

Required scope: pass:create

You must provide either userId or user, but not both.

FieldRequiredDescription
userIdConditionalID of an existing user
userConditionalInline user creation object (same fields as Create User)

Response:

{
  "id": "wp_abc456",
  "object": "wallet_pass",
  "userId": "usr_xyz789",
  "templateId": "tpl_abc123",
  "qrCodeValue": "ste.mp/Ab1x",
  "isPreviewPass": false,
  "createdAt": "2026-01-15T10:35:00Z",
  "updatedAt": "2026-01-15T10:35:00Z"
}

Get a Wallet Pass

# With template context
curl https://api.stemp.app/api/v1/templates/{templateId}/walletpasses/{walletPassId} \
  -H "Authorization: Bearer <token>"

# Direct access (no template ID needed)
curl https://api.stemp.app/api/v1/walletpasses/{walletPassId} \
  -H "Authorization: Bearer <token>"

Required scope: pass:read

Delete a Wallet Pass

# With template context
curl -X DELETE https://api.stemp.app/api/v1/templates/{templateId}/walletpasses/{walletPassId} \
  -H "Authorization: Bearer <token>"

# Direct access
curl -X DELETE https://api.stemp.app/api/v1/walletpasses/{walletPassId} \
  -H "Authorization: Bearer <token>"

Required scope: pass:delete

Pass Installation Status

Each pass tracks whether it has been added to a wallet:

StatusDescription
INSTALLEDUser has added the pass to their Apple or Google Wallet
UNINSTALLEDUser has removed the pass from their wallet

You can track installation events via webhooks (pass.installed, pass.uninstalled).

QR Codes

Every wallet pass has a unique qrCodeValue (e.g., ste.mp/Ab1x). This QR code can be scanned at the point of sale to identify the user and their pass.

Typical Integration Flow

  1. Create a user when a customer signs up in your system.
  2. Create a wallet pass for the user, linking it to a template.
  3. Send the notification email so the user can add the pass to their wallet.
  4. Scan the QR code at the point of sale to look up the pass.
  5. Add stamps based on the transaction.