Developers

Wivly Infrastructure API

Issue wallet passes, stamp and redeem them, and receive signed webhooks. A small, stable REST surface, documented in full before you pay for it.

The API is included from the Scale Up plan up.

Authentication

Every request carries an API key as a bearer token. Create keys from Settings → Developers in your dashboard; the full key is shown once, on creation, and stored only as a hash.

curl https://wivly.me/api/v1/passes \
  -H "Authorization: Bearer wivly_..." \
  -H "Content-Type: application/json" \
  -d '{"templateId":"tpl_123","customer":{"name":"Marco"}}'

Keys can be scoped to specific venues. A venue-scoped key can only act on passes belonging to those venues, which makes it safe to hand to a single location.

Key scopes

Every key carries exactly one scope. Pick the narrowest that does the job.

FULL

Everything below. Issue passes, stamp, redeem, notify, manage webhooks.

ISSUE_ONLY

Issue passes and read. Cannot stamp, redeem or notify — the right scope for a signup form on your own site.

READ_ONLY

GET requests only. The right scope for a reporting job or a dashboard you build yourself.

Rate limits

60 requests per minute per key. Over that, the API returns 429 and the request is not processed — retry after the next minute boundary rather than immediately.

Endpoints

All paths are relative to https://wivly.me/api/v1 and return JSON.

POST/passes

Issue a pass

Body: { templateId, customer?: { name?, email? } }. Returns serialNumber, appleUrl, googleSaveUrl. Venue-scoped keys can only issue on their own venues.

Scopes: FULL, ISSUE_ONLY

GET/passes/{serial}

Read pass state

Scopes: Any

PATCH/passes/{serial}

Stamp or redeem

Body: { action: "stamp" | "redeem", tier?: 0-2 }.

Scopes: FULL

POST/passes/{serial}/notify

Send a lock-screen message

Body: { message: string, max 200 chars }. Subject to the org's frequency cap and quiet hours.

Scopes: FULL

GET/events

Export analytics events

Query: since (ISO 8601), type. Paginated, 500 per page.

Scopes: Any

GET/analytics/venues

Cross-venue rollups

Query: days (1-365, default 30). Per-venue members, visits, repeat rate, redemptions, revenue, plus cross-venue movement.

Scopes: Any

GET/webhooks

List webhooks

Secrets are never returned.

Scopes: Any

POST/webhooks

Register a webhook

Body: { url, events?: string[] }. The signing secret is shown once, on creation.

Scopes: FULL

DELETE/webhooks/{id}

Delete a webhook

Scopes: FULL

Webhooks

Register an endpoint and Wivly posts to it when something happens. Deliveries are retried on failure.

Events

pass.addedpass.removedpass.scannedreward.unlockedreward.redeemedprepaid.soldprepaid.debitedprepaid.low_balanceprepaid.spent

Verifying a delivery

Every request carries an x-wivly-signature header: HMAC-SHA256 of the raw request body, keyed with your webhook secret. Compare it against the raw bytes before parsing, and use a constant-time comparison.

import { createHmac, timingSafeEqual } from "node:crypto";

const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const received = req.headers["x-wivly-signature"];
const ok =
  received.length === expected.length &&
  timingSafeEqual(Buffer.from(expected), Buffer.from(received));

Idempotency

Each delivery has a stable id in the body, alongside apiVersion "2026-01-01". A retry reuses the id, so store it and ignore ids you have already handled.

Errors

Errors return a JSON body with an error message, and a code where one is useful.

401

Missing or invalid API key.

403

Your plan or the key's scope doesn't allow this. Code: PLAN_LIMIT when the plan is the reason.

404

No such pass, template or webhook — or it belongs to another organization.

429

Over 60 requests per minute for this key.

OpenAPI

The machine-readable spec, for Postman, Swagger, Stoplight or code generation. Public and unauthenticated: it describes the surface, not any data.

Open the OpenAPI spec →

Get a key

Create an account, then find API keys under Settings → Developers.

Turn regulars into a habit.

Live in under an hour. Free to start, no card required.

API reference · Wivly