Developers
Errors
Every refusal has the same shape: an HTTP status and one sentence in plain words. The sentence is written to be shown to your staff as it is.
The shape
{ "error": "amountMinor must be a whole number of shillings above zero, as a string, or null for any amount." }Branch on the status, not the words: the words may be improved. Every answer, good or bad, is sent with Cache-Control: no-store.
Statuses
FieldWhat it is
200 OKsuccessRead, updated, cancelled, or returned as it already was (a repeat with the same Idempotency-Key, an open collection with the same amount, a bill with an externalRef already sent).
201 CreatedsuccessSomething new was made: a collection, a learner or payer, a bill.
400 Bad Requestfix the requestThe body isn't JSON, or a field is missing or wrong, or a rule refused it (a label too long, a description not on your list, the wrong currency). The message names the field.
401 Unauthorizedfix the keyNo key, a key of the wrong shape, or a key that is wrong, stopped or past its 24 hours. See Keys.
403 Forbiddenwait for Tall GrassThe key is good but a gate is closed in your country, or your organisation isn't verified or has no data-processing agreement recorded. The message is the reason. See Gates.
404 Not Foundcheck the idNo collection, learner, payer or bill with that id or reference in your organisation. Other organisations' records are never visible: they answer 404 too.
409 Conflictthe state forbids itNo webhook address yet, an Idempotency-Key reused with another body, a payer of the wrong kind, a paid bill or collection, a payment on its way. Below.
429 Too Many Requestsslow downMore than 120 calls in the last minute with this key.
500 Internal Server ErrorretrySomething failed on Wellth's side. Try again in a minute: the calls below are safe to repeat.
503 Service Unavailabletell Tall GrassThis Wellth isn't fully set up (its address or the School API secret is missing). It won't fix itself.
A path that doesn't exist answers Next.js's 404 page (HTML, not JSON), and a method a path doesn't take answers 405 with no body. Check the method and path first when an error isn't JSON.
Messages, word for word
Send the school's API key as Authorization: Bearer wsk_...
That API key isn't valid. The school's director can make a new one in Wellth.No collection with that id for this school.
No learner with that externalRef for this school.
No payer with that payerRef: make it first with PUT /payers/:externalRef.
No bill with that id for this organisation.Set your webhook address first: Wellth must be able to tell your system about payments.
This Idempotency-Key was already used with a different request. Use a new key.
This collection is already paid.
This collection is already expired.
A payment on this share is on its way: it can't be stopped until that payment lands or fails.
This payer's balance comes from its bills: send bills, not balanceMinor.
Your system sends this payer's balance: send balanceMinor.
Your system sends this payer's balance: send the new balance instead of a bill.
This payer's number is retired.
This is a fleet rider: the remittance plan is kept in the Wellth portal, not sent by your system.
This payer is kept by its bills: retire it with DELETE /api/org/v1/payers/:externalRef.
That reference is a site's counter number.
Something was already paid on this bill, so it can't be cancelled.Too many calls: at most 120 a minute. Wait a minute and try again.
Something went wrong on Wellth's side. Try again in a minute.
Wellth's address (APP_URL) isn't set up, so payment links can't be made. Tell Tall Grass.
The School API isn't set up on this site yet (SCHOOL_API_SECRET). Tell Tall Grass.What is safe to retry
PUTlearners and payers,DELETE, everyGET, and cancelling: safe as they are. The same call twice leaves the same result.POST /collections: safe with anIdempotency-Key, and an open collection for the same externalRef and amount is returned rather than made twice anyway.POST /bills: safe when you send anexternalRef; the second call answers the bill already made.- Retry 429, 500 and timeouts after a wait (a minute, then longer). Don't retry 400, 401, 403, 404 or 409 unchanged: they will give the same answer.