Errors

Every error has an HTTP status, a readable error message and a stable code. The SDK throws them as CreditsError.

import { CreditsError } from "kredo";
 
try {
  await credits.charge({ user, action: "chat.message", ref });
} catch (err) {
  if (err instanceof CreditsError && err.isDeclined) return redirect(credits.buyUrl({ returnTo }));
  if (err instanceof CreditsError && err.isRetryable) return retryLater(ref); // same ref
  throw err;
}

Declined: the user can't pay this

isDeclined is true. Retrying won't help; send them to connect or buy, or change the request.

CodeMeaning
OverLimitOver the limit they approved for your app. Ask them to raise it
InsufficientBalanceNot enough credits. Send them to the buy page
LimitExpiredTheir approval for your app expired. Connect them again
OverMaxChargeAbove your app's largest allowed single charge
AppInactiveYour app is switched off
OverHeldCapturing more than was held
HoldExpiredThe hold expired. Release it and start a new one
OverSpentRefunding more than the user spent with your app

Retryable: try again later, with the same ref

isRetryable is true for statuses 429, 502 and 503, and when the network failed before any response.

CodeStatusMeaning
rate_limited429Too many requests. The SDK backs off and retries
DailyBudgetReached503The network hit its daily gas budget
AppBudgetReached503Your app hit its daily gas budget
RelayerLowBalance503The network is low on gas. Only releases, revokes and payouts go through
relayer502The transaction failed for another reason

Your request

CodeStatusMeaning
unauthenticated401Missing, unknown or revoked API key
invalid_request400A field is missing or wrong. issues lists each one
pricing400Unknown action, or a quantity a per-action price doesn't take
below_minimum400Below the smallest charge or send
test_mode_unsupported400This needs a live key
not_found404No such hold, key or app on your account
not_connected409The user hasn't connected your app yet
no_company409Set up your company before registering an app
too_many_apps, too_many_keys409At the limit of five apps, or ten active keys per app

Other vault rules

Status 422, from the vault contract:

CodeMeaning
HoldNotOpenThe hold was already captured or released
InsufficientEarningsNot enough unpaid earnings to cover the refund
RefUsedThat ref was already used for something else
EnforcedPauseThe network is paused for maintenance. Try again shortly