Skip to main content
This guide grants credits or entry passes to clients from your own systems — a reactivation campaign, a loyalty reward, or a correction after a manual refund. Everything here uses the secret API key and the Ultimate plan.
These calls run on your server only. The secret key reads your full client list and changes what clients hold, and CORS blocks it in browsers anyway.

Credits or passes?

Both work the same way; they differ in what the client ends up holding. Credits are a currency-like balance spent across whatever the studio prices in credits. One endpoint, one balance per client. Entry passes are counted entries that belong to a pass group. A client holds a separate balance per group, and an entry granted into one group cannot be spent in another.

1. Find your clients

Select your audience from the response — for example everyone whose bookings.lastBookingCompletedDate is more than six months old and whose marketingConsent is 1. Keep each client’s numeric id. That is what the grant endpoints expect, not the opaque _id.

2. Pick a pass group

Skip this step for credits, and skip it for passes if the studio has only one group.
Omit passGroupId entirely and entries land in the studio’s default group, which is what integrations written before multi-group support do.

3. Grant to one client

numberOfCredits is the client’s balance after the grant, not the amount you added. You send a duration, not an expiry date — Zenamu computes validTo from the moment of the grant. See Grant validity for the per-unit ceilings. Set price to 0 for a gift. The value is recorded on the grant, so use the real amount when the client actually paid you. Passes work identically at /v1/clients/123/passes, returning numberOfEntries and accepting an optional passGroupId.

4. Grant in bulk

Up to 100 clients per request. A client may appear only once in a batch. One call instead of a hundred keeps you well inside the rate limit:
sendEmail applies to the whole batch. Items are processed sequentially, in the order you send them.

Partial success

A bulk response is 200 even when items failed. The batch does not roll back.
Never treat a bulk 200 as “everything worked”. Check summary.failed.
summary.failedClientIds identifies the failed items. It does not make a retry appropriate by itself. Inspect each result and correct permanent errors first:
Never retry the whole batch — successful items would grant a second time. If you do retry, send only selected failed items after checking the cause.

Handling errors

In a bulk pass grant, a bad or plan-blocked passGroupId is a failed item inside the 200 response. It does not change the top-level status.
A 500 on a grant is not safely repeatable. The grant runs in a transaction, but the response never confirmed the outcome — re-read the client’s balance with GET /v1/clients before granting again, or you may double-credit them.

Suppressing emails

Every grant emails the client by default. Set sendEmail to false when you send your own campaign email, or when correcting a mistake the client should not hear about twice.