Format
- Requests and responses are JSON in UTF-8. Send
Content-Type: application/jsonon requests with a body; a body that is not valid JSON is 400malformed-json. - Property and query parameter names are
camelCase; enum values, error codes and event types arekebab-case. - Unknown request properties and query parameters are refused (400
data-failed-validationwith field codeunknown-fieldorunknown-parameter), so typos never get ignored silently. Accept-Language: deorenselects the language of money labels and of emails a request triggers (errormessages are English); the response carriesContent-Language. Localised content you stored is always returned in full.- Every response carries
X-Request-Id(yours if you sent a valid one, else generated) andCache-Control: no-store. Quote the request id when contacting support.
Response envelopes
id, resource (a constant kind such as voucher-set), domain fields, timestamps and _links to related resources. Nullable fields are always present, with null when unset; empty lists are [].
Identifiers
Ids are positive integers ("id": 42), in paths and bodies. A malformed id (/voucher-sets/abc) is 400 data-failed-validation with field code invalid-id. A well-formed id that does not exist or belongs to another partner is 404 with the resource’s code, for example voucher-set-not-found; both cases look the same.
Dates and times
- Timestamps are RFC 3339 in UTC with
Z, at millisecond precision: no fraction when the milliseconds are zero (2026-11-01T00:00:00Z), otherwise three digits (2026-10-21T17:42:10.120Z). Accept both shapes. - Timestamps you send need an offset (
Zor+01:00); they are converted to UTC. Without an offset → field codeinvalid-timestamp. - Dates are
YYYY-MM-DD, monthsYYYY-MM. Calendar periods (statistics) use your partner’stimezone. - Durations are integers named by unit, for example
gracePeriodMinutes. - Time ranges are half-open:
[from, to), filtered withgteandlt.
Money
All amounts are in euros (EUR).value is in cent.
Money is an object with the integer value and a label formatted in the response locale (de 5,00 €, en €5.00):
{"value": 500}; a label in a request is ignored. Amounts are never floats.
Localised text
Texts that consumers see are maps from locale to text, for example"name": {"de": "5 € Fahrguthaben", "en": "€5 ride credit"}. Every text you send must include your partner’s defaultLocale; supported locales are de and en. Responses always contain every locale you stored; pick the one you need client-side.
Long texts (description, termsText) are restricted Markdown: paragraphs, line breaks, bold, italic, lists, level 3-4 headings and https links. Render them with a sanitising Markdown renderer, never as raw HTML. See Content rules.
Large integers
Ids and counters such asmaxRedemptions, redemptionCount, remaining and used are unsigned 64-bit integers and may exceed 2^53. JavaScript’s JSON.parse loses precision above that: use a BigInt-safe parser (for example json-bigint or lossless-json). In OpenAPI these fields have format: uint64.
Updating resources
PATCHis a JSON Merge Patch: absent fields stay unchanged,nullclears a field, objects merge. Lists are replaced whole.PUTreplaces a whole document (for example the stock alert rule).- An update only writes the fields you changed, so two clients that change different fields of the same resource both succeed.
PATCH /provider/v1/voucher-sets/{id}with{}returns the set unchanged.
Concurrent changes
There is no optimistic locking: you send no precondition header and no revision number with an update, and the API never rejects a write because someone else changed the resource since you read it.- Last writer wins, per field. A
PATCHorPUTwrites only the fields that change. When two clients change the same field at the same time, the later write wins; when they change different fields of the same resource, both changes survive. For example, one client renaming a voucher set while another changes itsmaxRedemptionsboth succeed, and the set ends up with the new name and the new limit. - State changes are checked when they run. Commands (
:activate,:submit,:revoke, …) and edits that are only allowed in some statuses check the resource’s current status inside the request. If another change got there first, you get the operation’s own 409, for exampleinvalid-state-transition(the voucher set is no longer a draft, or was already activated), orvoucher-set-archived. These 409s are final for that request: read the resource again and decide whether the command still makes sense. Retrying unchanged gives the same answer. - Change requests can go stale. When AllRide corrects a live voucher set while your change request for it is open, the request is based on an older version and shows
isStale: true. AllRide cannot approve it (approval answers 409change-request-staleon AllRide’s side) until you edit it: anyPATCHof the request, even onlyproviderNote, rebases it on the current content. See Change requests. - 409
concurrent-updatemeans the request collided with another one on the same data and AllRide could not apply it after retrying internally. Nothing was written: retry it with backoff (with the sameIdempotency-Keyfor aPOST, see Idempotency). - If several people or systems edit the same resource, read it right before you change it, and agree who owns which fields.
Commands and batch operations
- Actions that are not plain updates are commands:
POST …/{id}:verb, for example:activate,:submit,:revoke. Most take an empty body. - Bulk operations use
POST …:batch(or…/vouchers:revoke) and are all or nothing: one invalid item fails the whole request and nothing is written. Item errors are listed inmore.validationErrors:propertynames the item (vouchers[17].value) andconstraintthe reason. - A command not allowed in the resource’s status → 409
invalid-state-transition.
Asynchronous jobs
Voucher uploads run asynchronously:- The command answers 202 with
Location(the job URL),Retry-After: 2and the job in its initial status. - Poll
Location, starting afterRetry-Afterand doubling the interval up to 30 seconds. - The job’s
statusends in a terminal value (completed,failed,cancelled), withfailureReasonon failure.
Location for the current state. Uploads also send the voucher-upload-completed and voucher-upload-failed webhooks.
Compatibility rules
Withinv1 AllRide adds, but never removes or changes. Your client must:
- ignore unknown response properties,
_linksrelations and error members; - treat enums as open sets and handle unknown values (for example a new
status); - not depend on the order of properties or of list items beyond the documented sort.