Skip to content

Submit Distribution Form

Public endpoint for end users to claim a pass through a published distribution. It finds or creates a client for the submitter, issues (or reuses) their pass, emails the wallet download links, and returns those links along with a short-lived client token.

Auth: Public — no Bearer token, no workspace membership.


Submit

POST /wallethero-api/distribution/submit

Request Body

FieldTypeRequiredDescription
distribution_idstring (UUID)YesTarget distribution. Must reference a distribution whose status is published.
emailstring (email)YesSubmitter's email address. Must be a valid email.
first_namestringYesSubmitter's first name (min 1 character).
last_namestringNoSubmitter's last name.
phonestringNo*Submitter's phone number (trimmed, max 50 characters). Top-level field, not a custom field — this is what the server checks when the distribution's form_fields_config marks phone required, and what it matches returning clients on (email-or-phone). A phone sent only as custom_fields.phone is still accepted and promoted, but send it here.
marketing_consentbooleanNo*Whether the submitter opted into marketing. *Must be true when the distribution's form_fields_config marks the consent checkbox required — enforced server-side. When set, the server also stamps consent provenance on the client (marketing_consent_at, marketing_consent_source: "distribution_form" / "embed_form", and marketing_consent_text — a snapshot of the consent label from form_fields_config).
custom_fieldsobject (Record<string, any>)NoCustom field values, keyed by field name (should match the distribution's form_fields_config).
referral_codestringNoReferral code of the inviting client. Trimmed; max 20 characters. Only attributed for brand-new clients.

Example Request

bash
curl -X POST "https://api.wallethero.app/wallethero-api/distribution/submit" \
  -H "Content-Type: application/json" \
  -d '{
    "distribution_id": "b7f0c9d2-1a3e-4c8b-9f2d-7e6a5c4b3a21",
    "email": "[email protected]",
    "first_name": "Jane",
    "last_name": "Customer",
    "phone": "+15551234567",
    "marketing_consent": true,
    "custom_fields": { "birth_date": "1990-04-17" },
    "referral_code": "FRIEND10"
  }'

Response (200) — New Pass

json
{
  "success": true,
  "isResend": false,
  "message": "Pass created successfully. Check your email for download links.",
  "data": {
    "pass_id": "9c1e2d3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
    "apple_pass_url": "https://passes.wallethero.app/apple/pass/9c1e2d3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f?token=1f6d0a9c2b7e4d8f0a3c5e7b9d1f3a5c",
    "google_pass_url": "https://passes.wallethero.app/google/pass/9c1e2d3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f?token=1f6d0a9c2b7e4d8f0a3c5e7b9d1f3a5c",
    "client_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Response (200) — Existing Pass Resent

When the submitter already has a pass for the distribution's project, the existing pass is reused and the email is resent.

json
{
  "success": true,
  "isResend": true,
  "message": "Your pass already exists! We've resent the download links to your email.",
  "data": {
    "pass_id": "9c1e2d3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
    "apple_pass_url": "https://passes.wallethero.app/apple/pass/9c1e2d3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f?token=1f6d0a9c2b7e4d8f0a3c5e7b9d1f3a5c",
    "google_pass_url": "https://passes.wallethero.app/google/pass/9c1e2d3f-4a5b-6c7d-8e9f-0a1b2c3d4e5f?token=1f6d0a9c2b7e4d8f0a3c5e7b9d1f3a5c",
    "client_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
  }
}

Response Fields

FieldTypeDescription
successbooleanAlways true on success.
isResendbooleantrue when an existing pass was reused and re-emailed instead of created.
messagestringHuman-readable status message (varies by isResend).
data.pass_idstring (UUID)Created or existing pass identifier.
data.apple_pass_urlstring (URL)Apple Wallet download URL. Includes a per-pass ?token= when PASS_DOWNLOAD_TOKEN_SECRET is configured; passserver requires it unless it runs with PASS_DOWNLOAD_REQUIRE_TOKEN=false.
data.google_pass_urlstring (URL)Google Wallet save URL. Includes the same per-pass ?token=.
data.client_tokenstring (JWT)Short-lived loyalty-portal token for deep-linking. May be omitted if generation fails. Do not persist it.

Errors

StatusCodeDescription
400INVALID_PAYLOADBody fails validation, distribution_id / pass_template_id not found, or a field marked required in the distribution's form_fields_config is missing (Missing required field(s): …) — including a required marketing-consent checkbox that was not affirmatively checked. referral_code is exempt: malformed codes are dropped, never rejected.
403FORBIDDENDistribution exists but is not published.

SDK

No SDK method matches this exact path. The SDK's PublicDistributionService.enroll() posts to the token-based /embed/distribution/:token/submit endpoint (documented separately). For this endpoint, call the REST endpoint directly.

WalletHero Documentation