Errors

Stable. Describes behaviour that is built and covered by tests in this repository.

Every error of the tenant API has the same shape, whatever went wrong:

{
  "error": {
    "code": "INVALID_ARGUMENT",
    "key": "gateway.request.invalid",
    "message": "…",
    "details": [{ "field": "events", "description": "…" }],
    "request_id": "…"
  }
}

Status and what to do

Code HTTP Meaning Retry?
INVALID_ARGUMENT 400 the request is malformed or a field is not valid no: fix the request
UNAUTHENTICATED 401 the key is missing, wrong or ended no: see Authentication
PERMISSION_DENIED 403 the key may not do this, or the environment is not open for it no
NOT_FOUND 404 there is no such object no
ALREADY_EXISTS, ABORTED, FAILED_PRECONDITION 409 the object exists, or its state does not allow this now no: read the state, then decide
REQUEST_TOO_LARGE 413 the body is over 1 MiB (usage events: also over 500 events) no: send less per request
RESOURCE_EXHAUSTED 429 you are over a rate limit or a quota yes, after the seconds in Retry-After
UNAVAILABLE 503 a dependency is not ready yes, with the same idempotency key
DEADLINE_EXCEEDED 504 the call took too long yes, with the same idempotency key

An INTERNAL error never carries its cause in the message, and neither does an UNAVAILABLE, DEADLINE_EXCEEDED, RESOURCE_EXHAUSTED or ABORTED error that comes from the network or a database rather than from Payrudder's own rules: its message is a plain sentence that quotes the request_id, and the key (common.unavailable, common.timeout, common.rate_limited, common.conflict) is what to branch on. An error Payrudder wrote itself for these codes (a quota, an invitation limit) keeps its own message. A request that timed out may or may not have been done: retry it only with an idempotency key, or read the state first. The SDKs retry 429 and 5xx for you with the same key.

A usage event is judged on its own inside a 202 answer: an event that cannot be counted is rejected with an error_code (the list is below) and does not fail the others. See Usage metering.

You do not have to catch a rejection in the answer to see it later. Every rejected event is kept for 14 days (at most 10 000 per environment, the oldest dropped first) and can be read back: the Rejected events section of the Connect page in the console, with the hint for each code, or GET /v1/rejected-events (filter by error_code and meter, page with page_token) and GET /v1/rejected-events/summary (the last 24 hours by code and by hour), for a key with the usage:read permission. A row holds the code and the message, the meter code and the customer id as you sent them, the event time and the idempotency key; the properties and the quantity are never stored. A row is written just after the answer, best effort, so it can be a moment late and, under a burst of rejections or a database problem, a rejection can be missing from the list; the answer you got is the record. The sandbox's log is emptied by a sandbox reset.

In the SDKs and the command line

The SDKs turn the status into one typed error and keep the fields of the envelope on it (status, code, key, message, details, request id, Retry-After). Branch on the type or on the key, never on the message.

Status Go (Error.Kind) TypeScript Python PHP (Payrudder\Exception\…)
401 KindAuthentication AuthenticationError AuthenticationError AuthenticationException
403 KindPermission PermissionError PermissionDeniedError PermissionException
404 KindNotFound NotFoundError NotFoundError NotFoundException
400, 422 KindValidation ValidationError ValidationError ValidationException
409 KindConflict ConflictError ConflictError ConflictException
429 KindRateLimit RateLimitError RateLimitError RateLimitException
5xx KindServer ServerError ServerError ServerException
no answer (DNS, refused, reset, timeout) KindConnection ConnectionError, TimeoutError APIConnectionError, APITimeoutError ConnectionException, TimeoutException
any other KindAPI PayrudderError APIError ApiException

A rejected usage event is not an error of the call: it is a result with status: "rejected" and an error_code, in all four SDKs.

The command line prints an API error as payrudder: 404 customer.not_found: … (request <id>) and exits 1; a rejected event prints its error_code and exits 1; a command line it cannot understand exits 2 without sending anything. When you ask for help, quote the request id.

The catalogue

The list below is generated from the code (docs/error-keys.md, written by the test of pkg/errkey when UPDATE_ERROR_KEYS=1 is set, and checked by it otherwise) and so is always complete. It leaves out the keys of the operator's and the console's own routes (admin, identity, support), which an integration of the tenant API never receives.

Usage event error codes

An event the API refuses comes back rejected with one of these codes and does not fail the rest of the batch. The console shows the same advice, in its six languages, under the test event and next to each entry of the Rejected events list on the Connect page (the list is also GET /v1/rejected-events).

error_codeMeaningWhat to do
UNKNOWN_METERNo meter has this code. Create the meter first.No meter has this code. Create the meter on the Meters page, or fix meter_code.
UNKNOWN_CUSTOMERNo customer has this external id. Create the customer first.No customer has this id. Create the customer first, or fix customer_external_id.
EVENT_TOO_OLDThe event_time is more than 35 days in the past.The event is more than 35 days old. Send usage soon after it happens; older usage cannot be counted.
EVENT_IN_FUTUREThe event_time is more than 5 minutes ahead of the server's clock.event_time is more than 5 minutes ahead of Payrudder's clock. Check your server's clock and send the moment the usage happened.
INVALID_EVENT_TIMEThe event_time is missing or is not an RFC 3339 instant.Send event_time as an RFC 3339 instant, for example 2026-11-03T10:15:00Z.
INVALID_QUANTITYThe quantity is not a non-negative decimal.Send quantity as a non-negative decimal, as text such as "1" or "1.25".
INVALID_QUANTITY_PRECISIONThe quantity has more decimal places than the meter's quantity_scale.The quantity has more decimal places than the meter allows. Round it to the meter's quantity_scale.
IDEMPOTENCY_KEY_REQUIREDA live key sent the event without an idempotency_key.A live key must send an idempotency_key with every event. Derive it from what happened (an order id) so a retry counts once.
IDEMPOTENCY_KEY_INVALIDThe idempotency_key is not 1 to 128 characters of letters, digits and _ . : -.Use 1 to 128 characters: letters, digits and _ . : -.
IDEMPOTENCY_KEY_REUSEDThe idempotency_key was used before for a different event.This key was used for a different event. Use a new key for a new event; retry the same event with the same key and the same content.
INVALID_PROPERTIESThe properties are too many or too large, or a UNIQUE meter's property is missing.Send at most 32 properties and 4 KiB in total, with text values, and include the property a UNIQUE meter counts.
INVALID_CORRECTIONA correction needs a reason of 1 to 500 characters, and the key of the event it corrects (not its own).A correction needs a reason of 1 to 500 characters and the key of the event it corrects (not its own key).
CORRECTION_UNKNOWN_EVENTNo event with the key in corrects is known: it was never accepted, or it is older than idempotency keys are kept (at least 45 days).No event with that key was found. It may never have been accepted, or it is older than idempotency keys are kept (at least 45 days).
CORRECTION_MISMATCHThe customer or the meter is not that of the event being corrected.A correction must name the same customer and the same meter as the event it corrects.
CORRECTION_UNSUPPORTED_METEROnly events of SUM and COUNT meters without a property filter can be corrected.Only events of SUM and COUNT meters without a property filter can be corrected.
CORRECTION_OF_CORRECTIONThe event is itself a correction: correct the original again, with the quantity it should have.The event is itself a correction. Correct the original event again, with the quantity it should have.

All keys

510 keys, 15 areas. The meaning is the English message the console shows for the key; the API's own message may differ in wording.

affiliate

Partner program

KeyMeaning
affiliate.bad_idThat is not a valid id.
affiliate.bad_kindThe kind must be commission or reversal.
affiliate.bad_page_tokenThis page link is not valid. Reload the list.
affiliate.bad_periodWrite the dates as YYYY-MM-DD, with the end after the start and at most a year apart.
affiliate.bad_sourceThe source must be link, code or api.
affiliate.bad_statusThe status must be pending, active or suspended.
affiliate.code_requiredA partner code is required.
affiliate.code_takenThis code is already taken. Partner codes are unique across the platform: choose another.
affiliate.commission.not_foundThis invoice earned no commission.
affiliate.customer_not_foundNo such customer.
affiliate.customer_requiredName the customer to attribute.
affiliate.email_takenA partner with this e-mail address already exists.
affiliate.not_foundNo such partner.
affiliate.payout.affiliate_inactiveA suspended or pending partner is not paid. Their balance is kept until you reinstate them.
affiliate.payout.not_foundNo such payout.
affiliate.payout.not_openThis payout is no longer open: it was paid or cancelled.
affiliate.payout.nothing_to_payAfter refunds this payout comes to nothing. Cancel it; the balance rolls forward.
affiliate.payout.tenant_not_activeThis live environment is not active, so no payout can be made or paid.
affiliate.portal.already_appliedYou are a partner of this seller already, or you have applied.
affiliate.portal.program_unavailableThis seller has no partner program open to applications.
affiliate.portal.try_againA code could not be made just now. Try again.
affiliate.program.coupon_inactiveThe coupon for referred customers is not active.
affiliate.program.coupon_not_foundThe coupon for referred customers does not exist.
affiliate.program.not_setThis environment has no partner program yet.
affiliate.promotion_code_not_foundNo such promotion code.

aggregator

Usage totals

KeyMeaning
aggregator.customer.bad_idThe customer id is not a valid id.
aggregator.meter.not_foundThis meter was not found.
aggregator.period.bad_idThe period must look like 2026-11.
aggregator.period.cannot_computeThe settings of this period cannot be worked out. Check the period and the account's time zone.
aggregator.period.frozenThis period is frozen or already closes within five seconds, so it cannot be closed early.
aggregator.period.not_sandboxPeriods can only be closed early in a sandbox account.
aggregator.replay.bad_job_idThe replay job id is not a valid id.
aggregator.replay.bad_stateThe replay job is not in a state where this can be done.
aggregator.replay.bad_tenant_idThe account id is not a valid id.
aggregator.replay.invalidThis replay request is not valid.
aggregator.replay.not_foundThis replay job was not found.
aggregator.store.unavailableUsage data is not available right now. Try again shortly.
aggregator.usage.bad_batch_sizeAsk for between 1 and the maximum number of usage keys at a time.

analytics

Usage analytics and reports

KeyMeaning
analytics.customer.bad_idThe customer id is not a valid id.
analytics.granularity.unknownThis granularity is not supported. Use hour or day.
analytics.query.exact_too_longExact queries cover at most one day. Use the estimated series for longer ranges.
analytics.query.invalidThis query is not valid. Check the meter, the period and the filters.
analytics.range.daily_too_longA daily series covers at most 400 days.
analytics.range.hourly_too_longAn hourly series covers at most 31 days.
analytics.range.requiredBoth the start and the end of the range are required.
analytics.store.unavailableAnalytics is not available right now. Try again shortly.
analytics.tenant.bad_idThe account id is not a valid id.
analytics.tenant.unknownThis account is not known to analytics.

assets

File uploads and downloads

KeyMeaning
assets.asset.bad_statusThe file is not in a state where this can be done.
assets.asset.cannot_abortThis file is already uploaded or finished. Abort the upload instead of completing it.
assets.asset.not_foundThe file was not found.
assets.asset.not_in_sessionThat file is not part of this upload session.
assets.asset.not_uploadableThis file can no longer be uploaded.
assets.download.not_readyOnly files that finished uploading can be downloaded.
assets.download.sign_failedThe download link could not be created. Try again shortly.
assets.list.bad_page_sizeThe page size must be between 1 and 500.
assets.list.bad_page_tokenThe page token is not valid. Start the list again.
assets.request.bad_idAn id in the request is not a valid id.
assets.session.bad_file_countA session takes between 1 and the maximum number of files.
assets.session.closedThe upload session is no longer open.
assets.session.not_foundThe upload session was not found.
assets.storage.quota_exceededThese files do not fit in the storage quota of this account.
assets.storage.sign_failedThe upload URLs could not be created. Try again shortly.
assets.storage.unavailableFile storage is not available right now. Try again shortly.
assets.upload.bad_from_partThe starting part is beyond the number of parts of this file.
assets.upload.bad_part_countAsk for a valid number of part URLs at a time.
assets.upload.bad_sha256The SHA-256 checksum must be 64 hexadecimal characters.
assets.upload.changedThe upload changed at the same moment. Try again.
assets.upload.content_type_mismatchThe content of the file does not match its declared type.
assets.upload.file_too_largeThe file is too large.
assets.upload.header_requiredThe first message of an upload must be the upload header.
assets.upload.invalid_filenameThe file name cannot be used.
assets.upload.multipart_goneThe multipart upload no longer exists. Start the upload again.
assets.upload.part_mismatchThe uploaded parts do not match the file.
assets.upload.size_mismatchThe size of the uploaded file does not match the declared size.
assets.upload.size_requiredThe size of the file is required for direct uploads.
assets.upload.unsupported_content_typeThis type of file is not supported.

audit

KeyMeaning
audit.filter.bad_accountThe account id is not valid.
audit.filter.bad_page_sizeThe page size must be between 1 and 200.
audit.filter.bad_tenantThe tenant id is not valid.
audit.filter.bad_timeThe dates are not valid, or the start is after the end.
audit.page_token.invalidThat page of the log is no longer valid. Reload the list.
audit.unavailableThe audit log could not be read from every service. Try again.

billing

Invoices, credits, credit notes, payment links and accounting

KeyMeaning
billing.accounting.bad_appThe app is not valid.
billing.accounting.bad_attachmentThe attachment is not valid.
billing.accounting.bad_categoryThe category is not one of the known categories.
billing.accounting.bad_dateDates look like 2026-10-21.
billing.accounting.bad_expenseAn expense needs a vendor (up to 120 characters), a note of at most 500 characters and an amount above zero.
billing.accounting.bad_granularityThe series is by day or by month.
billing.accounting.bad_page_sizeThe page size must be between 1 and 200.
billing.accounting.bad_page_tokenThe page token is not valid.
billing.accounting.bad_periodGive a first and a last day, in order.
billing.accounting.bad_recurringAn expense repeats monthly or yearly; its last day cannot be before its first.
billing.accounting.bad_ruleThe rule is not valid: check the vendor text, the percentages and the expected amount.
billing.accounting.expense_not_foundThere is no such expense.
billing.accounting.expense_voidedThe expense was voided and cannot be changed.
billing.accounting.inbox_item_not_foundThere is no such invoice waiting for review.
billing.accounting.range_too_longThe period is too long: five years at most, and a daily series up to 366 days.
billing.accounting.reason_requiredGive a reason of up to 200 characters to void an expense.
billing.accounting.rule_not_foundThere is no such rule.
billing.accounting.too_many_rulesA tenant may have at most 200 rules.
billing.accounting.unknown_currencyThe currency is not supported.
billing.credit_note.bad_amountThe credit amount is not valid: it must be more than zero and no more than what is left to credit on the invoice.
billing.credit_note.bad_idThe credit note id is not a valid id.
billing.credit_note.bad_page_sizeThe page size must be between 1 and 200.
billing.credit_note.bad_page_tokenThe page token is not valid. Start the list again.
billing.credit_note.bad_refund_idGive the provider's reference of the refund (one line, at most 200 characters) when the refund was made, and none when it was not.
billing.credit_note.bad_resolutionChoose whether the customer was paid back or not.
billing.credit_note.fully_creditedThis invoice has already been credited in full.
billing.credit_note.not_foundThis credit note was not found.
billing.credit_note.not_paidOnly a paid invoice can be credited.
billing.credit_note.note_too_longThe note can be at most 500 characters.
billing.credit_note.nothing_to_refundThere is nothing to refund to the card for this credit note.
billing.credit_note.reason_too_longThe reason can be at most 500 characters.
billing.credit_note.refund_not_failedOnly a credit note whose refund failed can be retried.
billing.credits.bad_amountThe amount must be a whole number of credits above zero.
billing.credits.bad_customerThe customer is not valid.
billing.credits.bad_expiryThe expiry date must lie in the future.
billing.credits.bad_keyThe idempotency key is too long (at most 128 characters).
billing.credits.bad_packA pack needs a name and credits and a price above zero.
billing.credits.bad_page_sizeThe page size must be between 1 and 200.
billing.credits.bad_page_tokenThe page token is not valid.
billing.credits.bad_quantityThe quantity must be 1 to 1000.
billing.credits.bad_reasonThe note is too long (at most 200 characters).
billing.credits.bad_sourceThe type must be promotion or manual.
billing.credits.bad_thresholdThe threshold must be 0 or a whole number of credits.
billing.credits.bad_validityThe validity must be 1 to 3650 days, or empty for credits that never expire.
billing.credits.insufficientThe customer has too few credits.
billing.credits.key_requiredAn idempotency key is required to spend credits.
billing.credits.key_reusedThis idempotency key was already used for a different request.
billing.credits.pack_inactiveThis credit pack is not on sale.
billing.credits.pack_not_foundThere is no such credit pack.
billing.credits.portal_cannot_buyThis portal link cannot buy credits. Ask for a new one.
billing.credits.unknown_currencyThis currency is not supported.
billing.customer.blockedThis customer is blocked, so no new purchase can be started.
billing.dead_letter.broker_unavailableThe message broker cannot be reached right now. Try again.
billing.dead_letter.invalidThis dead-letter request is not valid.
billing.dead_letter.not_configuredDead-letter operations are not set up on this deployment.
billing.dunning.bad_delayEach retry delay must be between 1 and 720 hours.
billing.dunning.too_many_retriesAt most 6 retry delays can be set.
billing.einvoice.bad_file_kindThe file kind must be xml or pdf.
billing.einvoice.bad_idThe e-invoice or account id is not a valid id.
billing.einvoice.bad_page_sizeThe page size must be between 1 and 200.
billing.einvoice.bad_page_tokenThe page token is not valid. Start the list again.
billing.einvoice.bad_statusThe status must be pending, issued, failed or cancelled.
billing.hosted.customer_unavailableThe customer could not be looked up right now. Try again shortly.
billing.hosted.seller_unavailableThe seller details could not be looked up right now. Try again shortly.
billing.hosted.tenant_unavailableThe account could not be looked up right now. Try again shortly.
billing.invoice.bad_customer_idThe customer id is not a valid id.
billing.invoice.bad_idThe invoice id is not a valid id.
billing.invoice.bad_page_sizeThe page size must be between 1 and 500.
billing.invoice.bad_page_tokenThe page token is not valid. Start the list again.
billing.invoice.not_foundThe invoice was not found.
billing.invoice.not_heldThis invoice's first charge is not held, so there is nothing to release or void here.
billing.invoice.pdf_failedThe invoice PDF could not be rendered. Check the invoice data.
billing.invoice.pdf_not_readyThe invoice PDF has not been rendered yet. Try again in a moment.
billing.invoice.pdf_sign_failedThe PDF download link could not be created. Try again shortly.
billing.invoice_link.bad_expiryThe link must expire in 1 to 365 days.
billing.invoice_link.bad_page_tokenThe page token is not valid. Start the list again.
billing.invoice_link.draft_invoiceA draft invoice cannot be shared by link.
billing.invoice_link.not_foundThe invoice link was not found.
billing.payment.already_paidThe invoice is already paid.
billing.payment.amount_mismatchThe payment is not for the amount of the invoice.
billing.payment.bad_amountThe amount must be a whole number of minor units above zero.
billing.payment.bad_dateThe received date is not valid or lies in the future.
billing.payment.bad_methodThe method must be bank transfer, cash or other.
billing.payment.bad_noteThe note can be at most 500 characters.
billing.payment.bad_referenceThe reference must be one line of at most 128 characters.
billing.payment.invoice_not_payableOnly an open or uncollectible invoice can be paid by hand.
billing.payment.method_unavailableChoose a payment method.
billing.payment.not_payableThe invoice's payment state does not allow a manual payment right now.
billing.payment.overpaymentThat is more than is outstanding. Record only the outstanding amount.
billing.payment.reference_reusedThis reference was already recorded with a different amount.
billing.payment_link.bad_amountThe amount must be a positive number of minor units.
billing.payment_link.bad_currencyThis currency is not supported.
billing.payment_link.bad_descriptionA description is required, at most 200 characters.
billing.payment_link.bad_keyThe idempotency key is too long (at most 200 characters).
billing.payment_link.bad_kindAmount, currency, description and customer belong to an ad-hoc link; an invoice link takes them from the invoice.
billing.payment_link.bad_pageThe page size must be 1 to 200.
billing.payment_link.bad_promotion_codeA promotion code is 2 to 40 letters, digits, - or _, and belongs to an ad-hoc or credit pack link; an invoice that exists is not changed.
billing.payment_link.bad_required_contractsA link can name each of the distance sales contract, the pre-information, the terms of service and the privacy notice once.
billing.payment_link.bad_statusThe status must be active, paid, expired or revoked.
billing.payment_link.consumedThis link has already been used.
billing.payment_link.customer_not_foundThere is no such customer.
billing.payment_link.customer_requiredA credit pack link needs the customer who receives the credits.
billing.payment_link.free_totalThis promotion code takes the whole price, which leaves nothing to pay. Grant the purchase directly instead.
billing.payment_link.idempotency_conflictThis idempotency key was used for a different payment link.
billing.payment_link.invoice_not_payableA paid or void invoice needs no payment link.
billing.payment_link.invoice_requiredA payment link of kind invoice needs an invoice.
billing.payment_link.not_foundThere is no such payment link.
billing.payment_link.pack_requiredA credit pack link needs a pack.
billing.portal_link.customer_not_foundThere is no such customer.
billing.portal_link.customer_requiredA customer is required.
billing.report.bad_group_byGroup by may name period, provider and country only.
billing.report.bad_limitThe limit must be between 1 and 500.
billing.report.bad_periodThe first and last period must look like 2026-10.
billing.report.period_orderThe first period cannot be after the last one.
billing.request.bad_idAn id in the request is not a valid id.
billing.rerating.bad_job_idThe re-rating job id is not a valid id.
billing.rerating.bad_plan_version_idThe plan version id is not a valid id.
billing.rerating.not_foundThis re-rating job was not found.
billing.rerating.run_not_completedThe billing run of that period is not completed yet.
billing.rerating.unavailableRe-rating could not start right now. Try again.
billing.rerating.unknown_plan_versionThat plan version does not exist.
billing.run.bad_periodThe period must look like 2026-11.
billing.run.not_closableThis period cannot be closed now.
billing.run.not_foundThere is no billing run for that period.
billing.run.period_openThat period has not closed yet, so it cannot be billed.
billing.run.retry_laterThe billing run could not advance right now. It will be retried.
billing.run.sandbox_onlyClosing a period now is only available for sandbox accounts.
billing.saga.event_not_possibleThis cannot be done while the invoice is in its current payment state.
billing.saga.not_foundThis invoice has no payment process yet: it is not finalized.
billing.saga.void_needs_confirmationThe payment of this invoice is unknown, so the payment provider may have charged it. Check at the provider that nothing was charged, then void the invoice and confirm that.
billing.sandbox.unknown_scenarioThis payment scenario does not exist. See the scenario catalogue for the list.
billing.storage.not_configuredFile storage is not set up on this deployment.
billing.tenant.bad_idThe account id is not a valid id.
billing.tenant.on_holdThis seller cannot take payments right now.
billing.upcoming.customer_not_foundThere is no such customer.

common

Errors that have no key of their own

KeyMeaning
common.already_existsIt already exists.
common.canceledThe request was cancelled.
common.conflictThe data changed while you were working on it. Reload and try again.
common.failed_preconditionThis cannot be done in the current state.
common.internalSomething went wrong on our side. Try again, and if it keeps failing look at the logs with the request id.
common.invalid_argumentSomething in the request is not valid.
common.not_foundIt was not found.
common.not_implementedThis is not supported yet.
common.permission_deniedYou are not allowed to do this.
common.rate_limitedToo many requests. Wait a moment and try again.
common.timeoutThe request took too long. Try again.
common.unauthenticatedSign in again: the token is missing or no longer valid.
common.unavailableThe service is not available right now. Try again shortly.

coupon

Coupons and promotion codes

KeyMeaning
coupon.already_appliedThis purchase already uses a coupon. Only one coupon per purchase.
coupon.already_usedYou have already used this code.
coupon.below_minimumThe purchase is below the minimum amount for this code.
coupon.code_takenA promotion code with this text already exists (codes are the same in any letter case).
coupon.currency_mismatchThis code does not work in the currency of this purchase.
coupon.customer_requiredThis code needs a known customer, so it cannot be used on a guest payment.
coupon.exhaustedThis code has been used up.
coupon.expiredThis code has expired.
coupon.first_purchase_onlyThis code is for a first purchase only.
coupon.inactiveThis code is no longer active.
coupon.not_applicableThis code does not work for this purchase.
coupon.not_foundThis code does not exist. Check it and try again.

einvoice

E-invoices

KeyMeaning
einvoice.account.default_in_useThis is the default e-invoice account. Make another account the default first, then remove this one.
einvoice.account.invalidThe e-invoice account settings are not valid for this provider.
einvoice.account.missingThis tenant has no e-invoice account for this environment. Set one up first.
einvoice.account.sandbox_mock_onlyA sandbox environment can only use the mock e-invoice provider.
einvoice.buyer.incompleteThe customer's tax data is incomplete: add the tax id (and tax office in Turkey) before issuing an e-invoice.
einvoice.cancel.unsupportedThis provider cannot cancel an issued e-invoice. Issue a credit note instead.
einvoice.document.not_failedOnly an e-document that failed can be retried.
einvoice.document.not_foundThis e-document does not exist.
einvoice.document.not_issuedOnly an issued e-document can be cancelled.
einvoice.file.not_readyThe file of this e-document is not available yet.
einvoice.provider.rejectedThe e-invoice provider rejected the document.
einvoice.provider.unavailableThe e-invoice provider is not reachable right now. It will be tried again.
einvoice.routing.invalidThe routing rules are not valid: each country is a two-letter code, listed once, and each account is a connected account.
einvoice.routing.unknown_accountA routing rule names an e-invoice account that is not connected.
einvoice.seller.incompleteThe seller's company data is incomplete: add the legal name and tax id in the e-invoice settings.
einvoice.setting.invalidThe e-invoice trigger must be off, finalized or paid.

env

Environment mismatches

KeyMeaning
env.request.mismatchThis request is for a different environment than the one it was sent to, so it was refused.
env.request.missingThis request does not say which environment it is for, so it was refused.

gateway

Authentication, rate limits and the format of requests

KeyMeaning
gateway.auth.permission_deniedThis API key lacks a permission this request needs. Use a key with the role or permission it names.
gateway.auth.tenant_not_activeThis environment is suspended or not active yet. Finish the go-live checklist, or contact support.
gateway.auth.tenant_read_onlyThis environment is read-only. Contact support.
gateway.dashboard.bad_periodThat period is not valid. Choose 7, 30 or 90 days, this year, or two days with the first not after the last.
gateway.dashboard.limits_unavailableUsage limits are not available right now, so this view cannot be built. Try again shortly.
gateway.dashboard.payments_unavailablePayments are not available right now, so this view cannot be built. Try again shortly.
gateway.dashboard.range_too_longA period can be at most two years.
gateway.geo.country_not_foundThere is no such country in the list.
gateway.geo.region_not_foundThere is no such region in the list.
gateway.geo.unavailableThe country lists are not available right now; type the region and city instead.
gateway.mail.suppression_not_foundThat address is not on the suppression list.
gateway.mail.unavailableThe mail log and the suppression list are not connected on this deployment, or the mail service did not answer. Try again in a moment.
gateway.payments.ledger_unreachableThe payment ledger cannot be reached right now. Try again shortly.
gateway.payments.not_configuredPayment providers are not set up on this deployment.
gateway.payments.unreachableThe payments service cannot be reached right now. Try again shortly.
gateway.rate_limit.exceededToo many requests of this kind. Wait a moment and try again.
gateway.region.unknownThat region is not available on this deployment. Choose one from the list.
gateway.region.wrongThis environment is served from another region. Send the request to the gateway of its region (see the X-Payrudder-Region and X-Payrudder-Region-Url headers).
gateway.request.bad_tenant_idThe account id is not a valid id.
gateway.request.invalid{field} is not valid: {detail}
gateway.request.malformed_jsonThe request body is not valid JSON.
gateway.request.too_largeThe request is too large.
gateway.request.unreadable_bodyThe request body could not be read.
gateway.route.not_foundThere is no such address in the API.
gateway.saas.events_quotaYour plan's limit of events for this month is reached. Upgrade to send more.
gateway.saas.invoice_not_payableThis invoice cannot be paid any more.
gateway.saas.unavailablePlans are temporarily unavailable. Try again in a moment.

ingest

Usage ingestion

KeyMeaning
ingest.backlog.fullIngestion is backed up right now. Nothing was accepted; retry later.
ingest.batch.bad_sizeA request must carry between 1 and 500 events.
ingest.db.conflictThe data changed at the same moment. Nothing was accepted; retrying is safe.
ingest.db.slowThe database was too slow. Nothing was accepted; retrying is safe.
ingest.db.timeoutIngestion timed out. Nothing was accepted; retrying is safe.
ingest.db.unavailableThe database is not available. Nothing was accepted; retrying is safe.
ingest.outbox.unavailableIngestion cannot hand events on right now. Try again shortly.
ingest.plans.unavailableThe plans service is not available, so events cannot be checked. Try again shortly.
ingest.rejected_events.bad_page_sizepage_size must be between 1 and 200
ingest.rejected_events.bad_page_tokenpage_token is not one this API gave
ingest.tenant.bad_timezoneThe time zone of this account cannot be used. Check it in the account settings.

limits

Limits

KeyMeaning
limits.counter.unavailableUsage counters are not available right now. Try again shortly.
limits.customer.bad_idThe customer id is not a valid id.
limits.meter.code_requiredThe meter code is required.
limits.meter.not_foundThis meter was not found.
limits.meter.unavailableThe meter could not be looked up right now. Try again shortly.
limits.period.bad_idThe period must look like 2026-11.
limits.reconcile.not_configuredReconciliation is not set up on this deployment.
limits.reconcile.unavailableReconciliation could not run right now. Try again shortly.

payments

Payments, provider accounts and bank transfers

KeyMeaning
payments.account.bad_settingsThese provider settings are not valid. Check the credentials and the required fields.
payments.account.endpoint_not_allowedOnly the provider's own live endpoint is allowed. Leave the endpoint out.
payments.account.health_check_failedThe provider did not accept these credentials. Check the keys, and that they are live keys.
payments.account.health_check_unreachableThe provider could not be reached to check these credentials. Try again in a moment.
payments.account.livemode_mismatchThis provider account points at the provider's other mode: a live environment needs the provider's live endpoint and live keys, a sandbox environment its test endpoint.
payments.account.not_foundThis account has no such payment provider set up.
payments.account.single_onlyBank transfer has one account per environment.
payments.account.sync_failedThe provider account was changed, but the bank details could not be passed on to the invoices. Send the request again.
payments.billing.failedThe billing service could not complete this. Try again shortly.
payments.billing.not_configuredBilling is not set up on this deployment.
payments.card.not_foundThe customer has no such stored card.
payments.charge.currency_not_supportedThis payment provider cannot charge in this currency.
payments.charge.pendingThe payment was accepted and is waiting to be settled.
payments.charge.provider_not_configuredNo payment provider is set up for this account.
payments.charge.rejectedThe payment provider rejected the request.
payments.charge.timeoutThe payment provider did not answer in time.
payments.checkout.currency_unsupportedThis provider cannot take a checkout payment in this currency.
payments.checkout.fields_requiredThe provider and the price reference are required.
payments.checkout.unsupportedThis provider has no hosted checkout.
payments.customer.not_readyThe customer could not be prepared at the provider.
payments.dispute.bad_idThis is not the id of a dispute.
payments.dispute.not_foundThe dispute was not found.
payments.dispute.note_requiredWrite something in the note.
payments.dispute.note_too_longA note is at most 2000 characters.
payments.failover.bad_targetA failover needs two different accounts that exist in the environment; a bank transfer cannot take part.
payments.failover.not_foundNo failover is set for that account.
payments.invoice.amount_requiredThe amount and the currency are required.
payments.invoice.bad_idThe invoice id is not a valid id.
payments.invoice.bad_idsThe invoice ids are not valid ids.
payments.invoice.buyer_incompleteThe provider needs more about this customer (phone, tax id, address) than the seller has on file.
payments.invoice.installment_unavailableThat number of instalments is not offered for this card and amount. Pay once, or choose one of the options on the page.
payments.invoice.no_instructionsThis provider has no payment instructions for this currency.
payments.invoice.not_liveOnly live invoices are paid through a provider.
payments.invoice.payment_in_progressA payment for this invoice is being started. Try again in a moment.
payments.invoice.return_url_requiredA return address is required for a checkout payment.
payments.invoice.unknown_methodThis payment method is not known.
payments.ledger.bad_limitThe limit must be between 1 and 1000.
payments.ledger.too_many_invoicesToo many invoices were asked for at once.
payments.migration.fields_requiredThe subscription and the target provider are required.
payments.migration.price_ref_requiredThis provider runs subscriptions itself: the price reference of its catalogue is required.
payments.plan.code_requiredThe plan code is required.
payments.plans.failedThe plans service could not complete this. Try again shortly.
payments.plans.not_configuredPlans are not set up on this deployment.
payments.provider.failedThe payment provider could not complete this. Try again shortly.
payments.provider.not_supportedThis payment provider does not support this.
payments.provider.unknownThis payment provider is not known.
payments.reconcile.bad_filterA filter value is not one this list knows.
payments.reconcile.bad_ledger_factA ledger fact needs the provider and its reference of the payment, and it only resolves a paid invoice the ledger lacks.
payments.reconcile.bad_periodThe period must look like 2026-10.
payments.reconcile.bad_resolutionChoose one of the listed ways to resolve it.
payments.reconcile.not_foundThat discrepancy does not exist.
payments.reconcile.note_requiredSay what you found out: a note is required.
payments.reconcile.resolvedIt is resolved. A run that finds it again reopens it.
payments.reconcile.too_longThat text is too long.
payments.reconcile.too_manyChoose between 1 and 100 discrepancies.
payments.refund.charge_unclearThe invoice has several successful charges and the refund does not single out one of them. Refund the customer at the payment provider, then record it on the credit note.
payments.request.bad_audit_filterThe audit log filter is not valid.
payments.request.bad_bodyThe request body must be valid JSON.
payments.request.bad_environmentThe environment must be sandbox or live.
payments.request.bad_tenantThe account id is not a valid id.
payments.request.too_largeThe request is too large.
payments.settlement.bad_csvThe report was not imported: a line is wrong, and nothing was kept.
payments.settlement.bad_fee_ruleThe fee rule is not valid: check the provider, the currency and the rate.
payments.settlement.bad_sinceThe start must be in the past and at most 400 days ago.
payments.settlement.fee_rule_not_foundThere is no such fee rule.
payments.subscription.cannot_cancelThis provider cannot cancel a subscription from here.
payments.subscription.change_refusedThis subscription change cannot be made.
payments.subscription.period_end_unknownThe end of the paid period at the provider is not known yet: no notification has told us.
payments.subscription.wrong_providerThis subscription is not run by this provider.
payments.tenant.unavailableThe account's data is being moved. Nothing was changed; try again in a moment.
payments.transfer.bad_amountThe amount must be a whole number of minor units above zero.
payments.transfer.bad_bodyThe request body could not be read: send valid JSON that is not too large.
payments.transfer.bad_currencyThe currency differs from the invoice's.
payments.transfer.bad_dateThe received date is not valid or lies in the future.
payments.transfer.bad_invoice_idThe invoice id is not a valid id.
payments.transfer.bad_noteThe note is too long (at most 500 characters).
payments.transfer.bad_outcomeThe outcome must be rejected or expired.
payments.transfer.bad_referenceThe bank reference is missing or not valid.
payments.transfer.bad_tenantThe account id is not a valid id.
payments.transfer.invoice_closedThe invoice is already paid or void.
payments.transfer.invoice_not_foundThis invoice was not found.
payments.transfer.not_a_transferThis invoice was not charged by bank transfer. Use Record payment instead.
payments.transfer.nothing_pendingThere is no pending transfer to reject.
payments.transfer.overpaymentThat is more than is outstanding. Record only the outstanding amount and handle the rest outside Payrudder.
payments.transfer.reference_reusedThis bank reference was already recorded with a different amount.
payments.transfer.unavailableThe payments service is not available right now. Try again in a moment.
payments.webhook.malformedThe notification could not be read.
payments.webhook.not_foundThere is no such notification address.
payments.webhook.not_recordedThe notification could not be recorded. Send it again.
payments.webhook.try_againThe notification could not be confirmed yet. Send it again.
payments.webhook.unverifiedThe notification could not be verified as coming from the provider.

plans

Customers, meters, packages, subscriptions, API keys and webhook endpoints

KeyMeaning
plans.api_key.app_archivedThis app was deleted, so it cannot have API keys.
plans.api_key.bad_roleThe role must be admin, billing, read only, send usage only or custom, with known permissions.
plans.api_key.tenant_not_activeThis environment is not active, so it cannot have API keys. Finish the go-live checklist first.
plans.app.bad_regionThe region may only have lower-case letters, digits and dashes, and at most 31 characters.
plans.app.bad_slugThe app slug may only have lower-case letters, digits and single dashes, and at most 60 characters.
plans.app.slug_takenThis account already has an app with that slug.
plans.appeal.existsAn appeal is open already. The operator will answer it.
plans.appeal.not_heldOnly an app the operator has suspended, frozen or banned can be appealed.
plans.appeal.not_openThis appeal was decided already.
plans.blocklist.fullA blocklist holds at most 1000 entries. Remove some before adding more.
plans.change.bad_prorationThe charge for this plan change cannot be worked out for this period.
plans.change.billed_in_arrearsThis subscription is billed in arrears. Change its plan with ChangePlan, which splits the month by time.
plans.change.fee_not_invoicedThe fee of the current period has not been invoiced yet. Try again in a moment.
plans.change.invalidThis change is not valid for the subscription.
plans.change.none_scheduledNo change is scheduled for this subscription.
plans.change.state_not_changeableA subscription in its current state cannot change plan.
plans.change.subscription_endedAn ended or ending subscription cannot change plan.
plans.change.use_change_subscriptionA subscription whose fee is invoiced in advance is changed with ChangeSubscription.
plans.common.already_existsIt already exists.
plans.common.broken_referenceThis refers to something that does not exist.
plans.common.forbiddenYou are not allowed to do this.
plans.common.not_foundIt was not found.
plans.contract.acceptance_not_foundNo such acceptance record.
plans.contract.body_requiredWrite the text first (at least one language).
plans.contract.consent_requiredThis seller starts the service at once: the customer must ask for it and acknowledge losing the right of withdrawal, each with its own box.
plans.contract.kind_unpublishedPublish a version of this agreement before you require it.
plans.contract.no_starterThere is a starter text in Turkish and English only.
plans.contract.not_acceptedThe customer has not accepted the agreements this seller requires.
plans.contract.refund_not_possibleA refund cannot be requested for this withdrawal: it is not accepted, names no invoice, or a refund was asked for already.
plans.contract.unknown_variableThe text uses a variable that does not exist. Use only the variables in the list.
plans.contract.version_not_foundNo such version.
plans.contract.version_staleA newer version of this text was published. Show the current one and ask again.
plans.contract.withdrawal_decidedThis withdrawal request cannot change to that status.
plans.contract.withdrawal_not_foundNo such withdrawal request.
plans.coupon.bad_page_tokenThe page token is not valid. Start the list again.
plans.coupon.bad_stateThe state must be active, inactive or empty.
plans.coupon.codes_exhaustedNot enough unused codes could be found. Try a longer prefix.
plans.coupon.fee_not_in_advanceA coupon takes something off a fee that is invoiced in advance. This subscription's fee is billed another way.
plans.coupon.none_on_subscriptionThis subscription has no coupon.
plans.coupon.subscription_endedAn ended subscription cannot take a coupon.
plans.customer.blockedThis customer is blocked, so nothing new can be started for them.
plans.customer.blocklistedThis customer matches a blocklist, so it cannot be created or changed this way.
plans.customer.quota_reachedThe customer limit of this account's plan has been reached.
plans.customer.tax_invalidThe customer's tax id or tax office is not valid.
plans.customer_appeal.existsAn appeal of this customer is open already.
plans.customer_appeal.not_blockedThis customer is not blocked, so there is nothing to appeal.
plans.customer_appeal.not_openThis appeal was decided already.
plans.fee.invalid_periodThe billing period of this subscription cannot be worked out.
plans.fee.not_period_startThis is not the start of a billing period.
plans.mail.unknown_categoryThis mail category does not exist.
plans.mail_integration.account_existsThis app already has its own e-mail account with that name. Remove it, or give the shared account another label.
plans.mail_integration.default_in_useThis is the default e-mail account. Make another account the default first, then remove this one.
plans.mail_integration.inheritedThis e-mail account belongs to the organisation. Change or remove it on the organisation's integrations page.
plans.mail_integration.live_onlyThe sandbox sends its mail to the sandbox inbox. Connect an e-mail provider in the live environment.
plans.mail_integration.not_configuredE-mail providers are not set up on this deployment.
plans.mail_integration.not_connectedNo e-mail provider is connected.
plans.mail_integration.refusedThe e-mail provider did not accept this key.
plans.mail_integration.seal_failedThe key could not be stored. Try again.
plans.mail_integration.shared_in_useApps still use this shared account. Stop them using it first.
plans.mail_integration.unknown_accountA rule names an e-mail account that is not connected.
plans.mail_integration.unreachableThe e-mail provider could not be reached. Check the address and try again.
plans.meter.changed_concurrentlyAnother meter version was created at the same moment. Try again.
plans.meter.quota_reachedThe meter limit of this account's plan has been reached.
plans.migration.abortedThe migration was aborted.
plans.migration.already_completedThe migration already completed.
plans.migration.cannot_abortThe migration has completed and cannot be aborted.
plans.migration.coupon_blocks_moveThis subscription has a coupon, which a provider-run or arrears-billed subscription cannot carry. Remove the coupon first.
plans.migration.state_not_movableA subscription in its current state cannot be moved to another provider.
plans.migration.subscription_endedThe subscription has ended or is ending, so it cannot be moved.
plans.override.customer_requiredSay which customer the limit is for.
plans.override.not_foundThis customer has no override on that meter.
plans.plan.no_fixed_feeThis plan version has no fixed fee for that interval in this currency.
plans.plan.no_metered_priceThis plan version has metered prices but none in this currency.
plans.price_change.date_differsAn open price change for these versions starts on another date. Withdraw it to make a new one.
plans.price_change.not_foundPrice change not found.
plans.price_change.pausedPrice changes are paused by the operator. Try again later.
plans.price_change.withdrawnThis price change was withdrawn. Make a new one.
plans.request.invalid{field} is not valid: {detail}
plans.saas.bad_resourceThat is not a resource a plan limits.
plans.saas.disabledPlans are not enabled on this installation.
plans.saas.downgrade_blockedYour usage does not fit that plan. Remove apps, members or keys first, then try again.
plans.saas.not_readyPlans are not ready yet. Try again in a moment.
plans.saas.platform_accountThe platform's own organisation has no plan.
plans.saas.quota.api_keysYour plan's limit of API keys is reached. Upgrade to create more.
plans.saas.quota.appsYour plan's limit of apps is reached. Upgrade to add more.
plans.saas.quota.membersYour plan's limit of members is reached. Upgrade to invite more people.
plans.saas.same_planThe organisation is on this plan already.
plans.saas.unknown_planThere is no such plan.
plans.subscription.already_linkedThis subscription is already linked to a payment provider.
plans.subscription.bad_periodThe billing period of this subscription cannot be worked out.
plans.subscription.billed_in_arrearsThis subscription is billed in arrears: no fee was paid in advance.
plans.subscription.changed_concurrentlyThe subscription changed at the same moment. Reload and try again.
plans.subscription.coupon_blocks_creditThis subscription has a coupon. Credit the unused part with a credit note on its fee invoice instead.
plans.subscription.endedThe subscription has already ended.
plans.subscription.ending_or_endedThe subscription has already ended or is already scheduled to end.
plans.subscription.no_scheduled_cancelThere is no scheduled cancellation to withdraw.
plans.subscription.period_overlapThis customer already has a subscription that overlaps that period.
plans.subscription.provider_currencyThis payment provider cannot charge in this currency. Choose another provider or currency.
plans.subscription.quantity_needs_advanceA quantity above 1 needs a subscription that Payrudder runs and bills in advance.
plans.subscription.run_by_providerThis subscription is run by a payment provider. Change it there.
plans.subscription.transition_not_allowedThis cannot be done in the subscription's current state.
plans.tenant.approval_pendingThe ban is recorded. A second operator must make the same request to apply it.
plans.tenant.bad_statusThe status must be active, suspended, frozen or banned.
plans.tenant.bad_transitionThis change of status is not possible for this environment.
plans.tenant.on_holdThis account is on hold: nothing new can be started.
plans.tenant.reason_requiredA ban, lifting a ban, or activating an environment without its checklist needs a reason.
plans.tenant.settings_immutableThe currency, time zone and environment of an account cannot be changed.
plans.tenant.unknownThis account is not known.
plans.webhook.not_configuredWebhooks are not set up on this deployment (the secrets key is missing).
plans.webhook.tenant_not_activeThis environment is not active, so it cannot have webhook endpoints. Finish the go-live checklist first.
plans.webhook.too_many_endpointsThe limit of webhook endpoints is reached. Delete one first.