Open dashboardwalletap.com

Errors and limits

The status codes the Walletap API answers with, the shape of an error, every error code, when to retry, and the limits on requests.

Web

Every failed request answers with a 4xx or 5xx status and a JSON body that says what went wrong. This page lists them all, with what to do about each.

The error body#

JSON
{
  "error": "Missing permission: passes.create",
  "code": "insufficient_scope"
}
FieldPresentMeaning
errorAlwaysA sentence for a person. Log it; do not match on its wording
codeOn some errorsA stable identifier to branch on. See Error codes
OthersOn some errorsContext for that error, such as reason, feature, limit or passCount

A validation error on PATCH /pass also carries details, the list of every problem found, and receivedData, the body as the API read it.

Status codes#

StatusMeansWhat to do
200Done—
201Created: a template, a file or an API key—
202Accepted: a badge change that takes effect a moment laterRead the result back shortly
204Deleted. No body—
400The request is malformed or a value is invalidFix the field named in error
401No key, or a key Walletap does not recogniseCheck the key. See 401
402The account's plan or billing does not cover thisChange the plan; another key will not help. See 402
403The key is real but may not do thisUse a key with the right scope. See 403
404Nothing matches, or it belongs to another accountCheck the ID
409The request conflicts with the current stateSee Error codes
413The uploaded file is over 10 MiBSend a smaller file
500Something failed on Walletap's sideRetry with backoff
502The wallet credential service behind access badges did not answerRetry with backoff
504An image URL did not answer within 10 secondsRetry, or upload the file directly

401 Unauthorized#

The request carried no key, or one that does not match an active key.

errorCause
API key required, Authentication required, API key is requiredNo key was sent
Invalid API keyThe key is mistyped, was rotated, or is disabled
You are not authorized for this actionOn the pass endpoints: the key is not recognised, or the pass belongs to another account
unauthorizedOn the access badge endpoints: no key was sent

POST /pass, GET /pass and the notify and resend endpoints read the key only from X-API-Key. A key sent there as Authorization: Bearer is not read, and the request answers 401.

402 Upgrade required#

The account is authenticated and the key is allowed to make the request, but the account's plan, trial or billing does not cover it. Every 402 carries "code": "upgrade_required". Retrying, or using another key, gives the same answer; the account owner has to change the plan or fix billing in Billing.

JSON
{
  "error": "Your free trial has ended.",
  "code": "upgrade_required",
  "reason": "trial_expired"
}

On POST /pass, reason says why no more passes can be issued:

reasonMeans
free_capEvery pass the free plan includes has been issued
trial_capEvery pass the trial includes has been issued
trial_expiredThe trial has ended
subscription_inactiveThe subscription is not active, for example after a failed payment
active_customers_pausedNew cards are paused: the account went over its monthly active-customer allowance two months running. Event tickets still issue

Elsewhere, feature names what the plan does not include, and for an allowance current and limit give the numbers:

featureAnswered by
apiAccessPOST /api-keys: the plan has no API access
templatesPOST /templates, duplicate: the template allowance is used up
templateTypePOST /templates, duplicate, PATCH /templates/{id}: the plan does not include this type of card
geofencesPOST or PATCH /templates: more locations than the plan covers
ticketCreditsPOST /pass for an event ticket: no ticket credits are left

See plans for what each plan includes.

403 Forbidden#

The key is real, but this request is beyond it.

errorCause
Missing permission: <scope>The key's scopes do not include <scope>. On /pass and the notify, resend and template notification endpoints, code is insufficient_scope
This API key is scoped and cannot perform owner actionsManaging API keys needs a Full access key. code is insufficient_scope
Insufficient permissions to view templatesGET /templates with a key that has no template scope
You don't have permission to access this resource…The template, pass or file belongs to another account
access badges not enabledThe account does not have access badges
Access badges are created in the dashboard…POST /templates with type: "access". code is access_badge_not_creatable_here

To decide between 401 and 403: 401 means "wrong credential", 403 means "right credential, not enough power". The exception is GET /pass, GET /passes and GET /passes/search, which also answer 401 for a pass or template that belongs to another account.

Error codes#

codeStatusMeans
upgrade_required402The plan or billing does not cover the request. See 402
insufficient_scope403A scoped key tried an owner action, or, on /pass and the notify, resend and template notification endpoints, the key lacks a scope
access_badge_not_creatable_here403Access badges are designed in the dashboard
template_has_passes409DELETE /templates/{id} on a template with issued passes. passCount says how many
issuance_blocked500Passes cannot be issued on this account. Contact support
no_registered_devices200POST /pass/{passId}/notify: no iPhone holds the pass, so nobody was alerted
unchanged_message200POST /pass/{passId}/notify: the same message is already on the pass

The access badge endpoints put their code in error itself:

errorStatusMeans
not_published409Invites need a published badge
users_list_failed, lifecycle_failed, passes_list_failed, user_update_failed, user_delete_failed502The wallet credential service did not answer. message has the detail

Retrying safely#

  • Reads (GET) are always safe to retry.
  • Field updates with PATCH /pass set values, so sending the same request twice leaves the same result.
  • Stamp operations are safe to retry when you send an idempotencyKey. Walletap remembers the last 20 keys on each card.
  • Balance operations are not deduplicated: an add sent twice adds twice. Read the pass before retrying, or state the new total with "operation": "set".
  • Issuing with POST /pass creates a new pass, and delivers it, every time. If a request timed out, look the pass up with GET /pass by its externalId before you send it again.

For 500, 502 and 504, retry with exponential backoff: wait one second, then two, then four.

Limits#

WhatLimit
Passes in one POST /pass1 to 10
Templates per page of GET /templates15 by default, 100 at most
Stamp counts0 to 50
Pass field valuesStrings or numbers
Template and duplicate names1 to 200 characters
Places in a template's locationsUp to 10, and no more than the plan covers
Image upload10 MiB; a URL is fetched for at most 10 seconds
Badge invite validity1 to 365 days, 30 by default
API key label60 characters, in the dashboard
Google Wallet notificationsThree per pass in 24 hours, set by Google

Next steps#