Skip to main content

Overview

Dodo Payments API uses standard HTTP status codes and custom error codes to indicate the success or failure of API requests. When an error occurs, the API returns an appropriate HTTP status code and a JSON response containing detailed information about the error. Each error response includes:
  • An HTTP status code indicating the general category of the error
  • A specific error code that identifies the exact nature of the error
  • A human-readable error message explaining what went wrong
  • Additional details about the error when applicable
Understanding these error codes and their meanings is crucial for:
  • Debugging integration issues
  • Implementing proper error handling in your application
  • Providing meaningful feedback to end users
  • Maintaining a robust payment processing system
These are API and business-logic errors. For card decline reasons returned on a failed payment (such as INSUFFICIENT_FUNDS or CARD_DECLINED), see the Transaction Failures reference instead.

Standard API Error Codes

HTTP StatusNameDescription
400Bad RequestThe request was malformed or contained invalid parameters
401UnauthorizedAuthentication failed or API key is invalid
403ForbiddenThe API key doesn’t have permission to access the requested resource
404Not FoundThe requested resource doesn’t exist
405Method Not AllowedThe HTTP method is not supported for this endpoint
409ConflictThe request conflicts with the current state of the resource
422Unprocessable EntityThe request was well-formed but contained semantic errors
429Too Many RequestsRate limit exceeded
500Internal Server ErrorAn unexpected error occurred on our servers
502Bad GatewayThe server received an invalid response from an upstream server
503Service UnavailableThe service is temporarily unavailable
504Gateway TimeoutThe server timed out while waiting for an upstream response

Error Response Format

When an error occurs, the API returns a JSON response with the following structure:
{
  "code": "UNSUPPORTED_COUNTRY",
  "message": "Country AI currently not supported"
}

Error Codes Reference

The error codes below are grouped by the area of the API they relate to. Each entry lists the condition that triggers it and the message the API returns.

Authentication & Account

  • UNAUTHORIZED
    • Trigger: No API key or invalid token / scope
    • Message: You are not authorised to perform this action
  • MERCHANT_NOT_LIVE
    • Trigger: Business still in test/sandbox mode
    • Message: Merchant is not live

Payments & Checkout

  • CHECKOUT_SESSION_CONSUMED
    • Trigger: Checkout session has already generated a payment
    • Message: Checkout session has already been consumed
  • NO_ELIGIBLE_PAYMENT_METHODS
    • Trigger: After filtering, nothing left
    • Message: No eligible payment methods found
  • PAYMENT_NOT_SUCCEEDED
    • Trigger: Attempt to refund/process unsuccessful payment
    • Message: The provided payment has not succeeded
  • PREVIOUS_PAYMENT_PENDING
    • Trigger: Attempt to create charge while previous is in non-terminal state
    • Message: Cannot create new charge as previous payment is not successful yet
  • UNSUCCESSFUL_PAYMENT_ID
    • Trigger: Payment ID references unsuccessful payment
    • Message: The Payment ID has an unsuccessful status.

Connectors & BYOP

These errors relate to merchant-owned payment connectors (Bring Your Own Processor).
  • BYOP_CONNECTOR_DISABLED
    • Trigger: Updating a payment method on a subscription routed through a disabled BYOP connector
    • Message: The subscription is routed through the merchant’s own (BYOP) connector which is currently disabled
  • BYOP_CUSTOM_INVOICE_ADDRESS_MISSING
    • Trigger: A merchant-routed (BYOP) payment is missing the required custom invoice address
    • Message: BYOP custom invoice address is required when a payment is routed through the merchant’s connector
  • CONNECTOR_LABEL_ALREADY_EXISTS
    • Trigger: Creating a connector with a label that already exists
    • Message: A connector with this label already exists. Please choose a different label.

Refunds

  • EXISTING_REFUND_REQUEST_PROCESSING
    • Trigger: Previous refund request still being processed
    • Message: A refund request with status “Pending” is still being processed
  • LINE_ITEM_FULLY_REFUNDED
    • Trigger: Attempt to refund already fully refunded line item
    • Message: Line item has been fully refunded cannot be refunded further.
  • LINE_ITEM_NOT_FOUND
    • Trigger: Item ID not part of the referenced payment
    • Message: Line item not found in payment
  • LINE_ITEM_PRORATED
    • Trigger: Refund or update attempted on a prorated line
    • Message: Line item cannot be refunded because its prorated
  • LINE_ITEM_REFUND_AMOUNT_TOO_HIGH
    • Trigger: Refund amount > paid amount (tax incl.)
    • Message: Line item requested refund amount including tax is which is above the paid amount
  • LINE_ITEM_REFUND_AMOUNT_TOO_LOW
    • Trigger: Refund amount below minimum threshold
    • Message: Line item requested refund amount is which is too low
  • NOTHING_TO_REFUND
    • Trigger: No refundable amount remains; all positive line items already fully refunded
    • Message: No refundable amount remaining. All positive line items have been fully refunded.
  • PARTIAL_REFUND_NOT_ALLOWED
    • Trigger: Partial refund attempted on a payment method that only supports full refunds
    • Message: Partial refunds are not allowed for this payment method
  • PAYMENT_ALREADY_REFUNDED
    • Trigger: Duplicate refund
    • Message: This payment has already been refunded
  • PAYMENT_HAS_BEEN_REFUNDED
    • Trigger: Payment has been fully refunded
    • Message: The Payment ID has been fully refunded.
  • REFUND_AMOUNT_EXCEEDS_PAID_AMOUNT
    • Trigger: Aggregate refund amount > paid amount
    • Message: The calculated refund amount is larger than the paid amount
  • REFUND_WINDOW_EXPIRED
    • Trigger: Outside allowable refund window
    • Message: Refunds cannot be initiated days after payment creation. Contact support@dodopayments.com.
  • ZERO_AMOUNT_PAYMENT_REFUND_NOT_ALLOWED
    • Trigger: Attempt to refund zero-amount payment
    • Message: Cannot refund a payment with zero currency amount

Subscriptions & Add-ons

  • ADDONS_IN_USAGE_BASED_BILLING_NOT_SUPPORTED
    • Trigger: Attempt to add addons to usage-based billing subscriptions
    • Message: Addons in Subscriptions are not supported for Usage Based Billing
  • ADDONS_NOT_ALLOWED_FOR_ON_DEMAND
    • Trigger: Attempt to add addons to on-demand subscriptions
    • Message: Addons are not allowed for on demand subscriptions
  • CANCEL_SCHEDULED_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED
    • Trigger: Customer Portal attempts to cancel a scheduled plan change while the business has disabled that action
    • Message: Cancelling scheduled plan change is disabled for customer portal.
  • CHARGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION
    • Trigger: Attempt to charge subscription scheduled for cancellation
    • Message: Subscription scheduled for cancellation
  • CUSTOMER_HAS_EXISTING_SUBSCRIPTION
    • Trigger: Creating a subscription for a customer who already has one, when multiple subscriptions per customer are not allowed
    • Message: Customer has an existing subscription. To allow multiple subscriptions per customer, change business settings
  • DO_NOT_BILL_NOT_ALLOWED_IN_CUSTOMER_PORTAL
    • Trigger: do_not_bill proration mode used in a Customer Portal plan change
    • Message: do_not_bill proration mode is not allowed in the customer portal
  • DUPLICATE_ADDON_IDS_IN_REQUEST
    • Trigger: Same addon_id appears more than once in the request
    • Message: Duplicate addon IDs are not allowed
  • INACTIVE_SUBSCRIPTION_PLAN_CHANGE_NOT_SUPPORTED
    • Trigger: Plan change on inactive subscription
    • Message: Changing plans is not supported for inactive subscriptions
  • INVALID_PRORATION_MODE_WITH_NEXT_BILLING_DATE
    • Trigger: A proration mode other than full_immediately used with effective_at: next_billing_date
    • Message: Only full_immediately proration mode is allowed with effective_at: next_billing_date
  • MISSING_ADDON_IDS
    • Trigger: addon_id list empty or unknown IDs
    • Message: One or more product IDs do not exist:
  • ON_DEMAND_PLAN_CHANGE_NOT_SUPPORTED
    • Trigger: Plan swap not allowed for on-demand
    • Message: Changing plans is not supported for on demand subscriptions
  • ON_DEMAND_USAGE_BASED_BILLING_NOT_SUPPORTED
    • Trigger: Attempt to use on-demand with usage-based billing
    • Message: On Demand Subscriptions are not supported for Usage Based Billing
  • ONE_TIME_PRODUCTS_NOT_ALLOWED_FOR_ON_DEMAND
    • Trigger: One-time product added to an on-demand subscription
    • Message: One-time products are not allowed for on demand subscriptions
  • PENDING_PLAN_CHANGE_EXISTS
    • Trigger: New plan change requested while a previous one is still awaiting payment
    • Message: A pending plan change already exists for this subscription. Please wait for the current payment to complete.
  • PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED
    • Trigger: Plan change via Customer Portal while the business has disabled it
    • Message: Subscription plan change for customer portal is disabled.
  • PLAN_CHANGE_NOT_ALLOWED_FOR_SCHEDULED_CANCELLATION
    • Trigger: Plan change attempted on subscription scheduled for cancellation
    • Message: Subscription scheduled for cancellation
  • SCHEDULE_PLAN_CHANGE_FOR_CUSTOMER_PORTAL_DISABLED
    • Trigger: Scheduling a plan change via Customer Portal while the business has disabled it
    • Message: Scheduling plan changes is disabled for this business.
  • SCHEDULED_PLAN_CHANGE_EXISTS
    • Trigger: Creating a scheduled plan change when one already exists
    • Message: A scheduled plan change already exists for this subscription. Please cancel the existing scheduled change before creating a new one.
  • SCHEDULED_PLAN_CHANGE_NOT_FOUND
    • Trigger: Referencing or cancelling a scheduled plan change that does not exist
    • Message: No scheduled plan change found for this subscription.
  • SUBSCRIPTION_EXPIRED
    • Trigger: Billing past ends_at
    • Message: Subscription expired cannot create new charges
  • SUBSCRIPTION_INACTIVE
    • Trigger: Status ≠ ACTIVE
    • Message: Subscription is not active
  • SUBSCRIPTION_NOT_ON_DEMAND
    • Trigger: Expected on-demand but got fixed interval
    • Message: Subscription is already not on demand
  • SUBSCRIPTION_PAYMENT_RETRY_LIMIT_EXCEEDED
    • Trigger: Subscription payment retries exceeded maximum attempts
    • Message: Maximum retry limit of 10 attempts exceeded for this subscription

Products, Cart & Brands

  • BRAND_MISMATCH
    • Trigger: Cart items belong to different brands
    • Message: All items in the product cart should belong to the same brand
  • BRAND_NOT_ENABLED
    • Trigger: Brand is disabled or not active
    • Message: Brand provided is not enabled
  • BRAND_SUBMISSION_NOT_ENABLED
    • Trigger: Brand verification resubmission feature not enabled
    • Message: Brand verificatin resubmission is not enabled
  • FILE_IN_USE
    • Trigger: Deleting a digital product file still referenced by active entitlement grants (pass ?force=true to override)
    • Message: Digital file is referenced by active grants
  • INVALID_SUGGESTED_PRICE
    • Trigger: PWYW price < minimum allowed price
    • Message: Suggested Price cannot be lower than minimum price. In case of pay what you want, price is considered as minimum accepted amount
  • LOCALIZED_PRICE_ALREADY_EXISTS
    • Trigger: A localized price already exists for this product and country/currency
    • Message: A localized price for this product and country/currency already exists
  • LOCALIZED_PRICE_DUPLICATES_BASE
    • Trigger: Localized price duplicates the product’s base currency/country
    • Message: Localized price duplicates the product’s base currency/country
  • LOCALIZED_PRICE_SHAPE_MISMATCH
    • Trigger: Localized price shape does not match the product’s pricing_mode
    • Message: Localized price shape does not match the product’s pricing_mode
  • MISSING_PRODUCT_INFORMATION
    • Trigger: Product exists but mandatory info missing
    • Message: Product exists but other mandatory information is missing or invalid
  • PAY_AS_YOU_WANT_AMOUNT_REQUIRED
    • Trigger: Price missing for PWYW product
    • Message: Amount is mandatory for pay as you want product
  • PRODUCT_CART_EMTPY
    • Trigger: Empty product cart submitted
    • Message: product_cart is empty (the error code is intentionally spelled EMTPY to match the exact value the API returns)
  • PRODUCT_COLLECTION_IS_DELETED
    • Trigger: Operating on a product collection that has been deleted
    • Message: No message
  • PRODUCT_COLLECTION_MUST_HAVE_PRODUCTS
    • Trigger: Removing the last product (or last group with products) from a collection
    • Message: Cannot delete the last product in a collection. Archive the collection instead.
  • PRODUCT_IS_DELETED
    • Trigger: Product soft-deleted
    • Message: No messages
  • PRODUCT_PRICING_MODE_REQUIRED
    • Trigger: Adding localized prices before the product’s pricing_mode is set
    • Message: Product pricing_mode must be set before adding localized prices
  • SLUG_ALREADY_TAKEN
    • Trigger: The requested product slug / short URL is already in use
    • Message: Slug is already taken
  • UNABLE_TO_EDIT_PRIMARY_BRAND
    • Trigger: Attempt to update primary brand via regular API
    • Message: Primary brand cannot be updated via this API endpoint.

Discounts

  • DISCOUNT_ALREADY_USED_ON_SUBSCRIPTION
    • Trigger: Re-applying a discount that has already been used on this subscription
    • Message: This discount has already been used on this subscription
  • DISCOUNT_CODE_ALREADY_EXISTS
    • Trigger: Duplicate discount code creation
    • Message: Discount Code already exists
  • DISCOUNT_CODE_EXPIRED
    • Trigger: Discount code past its expires_at date
    • Message: Discount code expired
  • DISCOUNT_CODE_USAGE_LIMIT_EXCEEDED
    • Trigger: Discount reused after usage_limit reached
    • Message: Usage limit cannot be less than times_used / Discount code hit usage limit
  • DISCOUNT_NOT_APPLICABLE_TO_NEW_PRODUCT
    • Trigger: Plan change to a product the existing discount does not apply to
    • Message: Discount not applicable to the new plan’s product
  • DISCOUNT_NOT_AVAILABLE_FOR_ON_DEMAND
    • Trigger: Code applied to on-demand subscription
    • Message: Discount coupon not available for on demand subscriptions
  • DISCOUNT_NOT_AVAILABLE_FOR_PRODUCT
    • Trigger: Code applied to unrelated product(s)
    • Message: Discount coupon not available for this product
  • INVALID_DISCOUNT_CODE
    • Trigger: Code does not exist / not applicable
    • Message: Invalid Discount Code / Discount Code cannot be applied to any product in the cart
  • INVALID_PERCENTAGE
    • Trigger: Percent amount > 100% (or 10,000 basis points)
    • Message: Percentage amount cannot be more than 10000 / Discount code amount cannot be more than 100%
  • UNSUPPORTED_DISCOUNT_TYPE
    • Trigger: Flat-amount discounts, etc., not yet live
    • Message: Only percentage discount codes are supported for now

License Keys

  • ACTIVATION_LIMIT_LESS_THAN_CURRENT_AMOUNT
    • Trigger: License-key activations: new limit < existing instance count
    • Message: New activation limit cannot be less than current instances count
  • INACTIVE_LICENSE_KEY
    • Trigger: Key status ≠ ACTIVE
    • Message: License key is not active
  • LICENSE_KEY_LIMIT_REACHED
    • Trigger: Activations = limit
    • Message: License key activation limit reached
  • LICENSE_KEY_NOT_FOUND
    • Trigger: Instance ID or key ID invalid
    • Message: License key instance not found or does not belong to this license key
  • NO_EXPIRY_ON_SUBSCRIPTION_LICENSE_KEYS
    • Trigger: Attempt to set expiry on sub-based key
    • Message: Cannot set expiry date for subscription-based license key

Usage-Based Billing & Meters

  • DUPLICATE_METER_IDS_IN_REQUEST
    • Trigger: Same meter ID appears multiple times in request
    • Message: Duplicate Meter Ids are not allowed
  • INVALID_QUANTITY
    • Trigger: Invalid quantity specified for usage-based pricing
    • Message: Only 1 quantity allowed in usage based price products
  • METER_IS_DELETED
    • Trigger: Attempt to use deleted meter
    • Message: The Meter is already been deleted
  • MISSING_METER_IDS
    • Trigger: Meter ID list empty or contains invalid IDs
    • Message: One or more meter IDs do not exist:

Credit-Based Billing

  • CREDIT_ENTITLEMENT_IS_DELETED
    • Trigger: Operating on a credit entitlement that has been deleted
    • Message: The credit entitlement has already been deleted
  • CREDIT_ENTITLEMENT_NAME_ALREADY_EXISTS
    • Trigger: Creating a credit entitlement with a name that already exists
    • Message: A credit entitlement with this name already exists
  • OVERAGE_LIMIT_EXCEEDED
    • Trigger: A usage or credit deduction would exceed the configured overage limit
    • Message: Overage limit exceeded

Wallet

  • INSUFFICIENT_WALLET_FUNDS
    • Trigger: Wallet balance < debit amount
    • Message: Insufficient funds in wallet
  • NEGATIVE_BALANCE_ADJUSTMENT
    • Trigger: Attempt to make wallet balance negative
    • Message: Wallet balance is not allowed to be made negative

Currency, Tax & Region

  • EXCHANGE_RATE_NOT_FOUND
    • Trigger: No FX rate for from → to currency pair
    • Message: Exchange rate not found to convert from Currency to Currency
  • INVALID_TAX_ID
    • Trigger: VAT/GST/TIN failed validation
    • Message: Tax Id is invalid
  • REQUEST_AMOUNT_BELOW_MINIMUM
    • Trigger: Amount < product minimum
    • Message: Amount cannot be less than minimum amount specified for the product
  • TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT
    • Trigger: Combined cart total < gateway minimum
    • Message: Minimum amount of is required to process payment
  • UNSUPPORTED_BILLING_CURRENCY
    • Trigger: Subscriptions restricted to USD
    • Message: Non USD billing currency is not supported for subscriptions
  • UNSUPPORTED_COUNTRY
    • Trigger: Geo not yet supported
    • Message: Country currently not supported
  • UNSUPPORTED_CURRENCY
    • Trigger: Product or addon currency invalid
    • Message: Currency is not currently supported / Only USD and INR products supported currently / Only USD and INR supported for addon price / Can only request USD or INR for billing_currency / Currency Not Supported / Unexpected currency for Indian card subscripitons
  • UNSUPPORTED_TAX_CATEGORY
    • Trigger: Tax category string not in enum
    • Message: Category currently not supported

Validation & Requests

  • DUPLICATE_LINE_ITEMS_IN_REQUEST
    • Trigger: Same item_id appears twice in items[]
    • Message: Duplicate item_ids specified in items array
  • INVALID_QUERY_PARAMS
    • Trigger: Mutually exclusive / malformed query parameters
    • Message: Query params should only contain either time_frame or (start, end)
  • INVALID_REQUEST_BODY
    • Trigger: Malformed JSON or schema violation
    • Message: Your request body is invalid. Please check your request headers and object.
  • INVALID_REQUEST_PARAMETERS
    • Trigger: Semantics wrong (e.g. date in past)
    • Message: Cannot change next_billing_date to past time
  • MAXIMUM_KEYS_REACHED
    • Trigger: Metadata / custom-fields exceeded 50 pairs
    • Message: Exceeds 50 key-value pairs

General & System

  • INTEGER_CONVERSION_FAILURE
    • Trigger: Any integer ↔ string/decimal conversion that fails server-side
    • Message: Integer Conversion Failure
  • INTERNAL_SERVER_ERROR
    • Trigger: Uncaught exceptions; you should log details server-side
    • Message: No public message (generic 500)
  • NOT_FOUND
    • Trigger: Generic 404 for any missing resource
    • Message: Item not found (or more specific)
  • TOO_MANY_REQUESTS
    • Trigger: 429 rate-limit
    • Message: No messages
  • UNSUPPORTED_ACTION
    • Trigger: Unsupported action for resource type
    • Message: Changing plans for usage based subscriptions is not supported

Best Practices

  1. Always handle errors gracefully in your application
  2. Implement proper error logging
  3. Use appropriate error messages for end users
  4. Implement retry logic for transient errors
  5. Contact support for unresolved issues

Support

For additional help with error codes or integration issues, please contact our support team at support@dodopayments.com.
Last modified on June 17, 2026