# Authentication Types Source: https://api-reference.hyperswitch.io/essentials/authentication Overview of authentication types and authorization keys available in Hyperswitch. Hyperswitch supports multiple API key types, each designed for different authentication and authorization use cases. For security, **never expose secret or admin keys in client-side or mobile code**. Use publishable keys for public contexts. ## 1. API Key (Secret Key) * **Primary merchant authentication key for server-side API requests.** * Environment-specific prefix (`snd_`, `prod_`, etc.). * Used for server to server requests. * This key can be **generated and managed from the [Hyperswitch dashboard (sandbox)](https://app.hyperswitch.io/developers?tabIndex=1)**. * **Never expose this key in public code.** ## 2. Admin API Key * **Administrative key** with elevated privileges. * Used for system-level operations such as creating merchant and connector accounts. * Should only be used in secure, internal workflows. * Some API calls require an admin API key. **Do not confuse this with a regular API Key.** * The **admin API key is a configuration value that can be set at the time of deploying the Hyperswitch server**. * **Admin API keys for the hosted Hyperswitch environments (sandbox/production) are managed by Juspay and are not provided publicly.** You do **not** generate this key from the dashboard.\ Instead, **set your Admin API Key in your deployment configuration**: **For Docker Compose:**\ Update the value in your `docker_compose.toml` file: ```toml theme={null} # docker_compose.toml admin_api_key = "your_admin_key_here" ``` **For Helm Chart deployments:** Set the admin API key in your `values.yaml` file. ```yaml theme={null} # values.yaml adminApiKey: your_admin_key_here ``` Do **not** expose your admin API key publicly. Only trusted entities and trusted applications should have access to this value. Check the Docker Compose example for extra clarity: [See example in the Hyperswitch repository](https://github.com/juspay/hyperswitch/blob/main/config/docker_compose.toml) ## 3. Publishable Key * **Client-side key** with limited permissions. * Safe for use in public client-side (web or mobile) code. * Prefix: `pk_{environment}_{uuid}`. * Generated during merchant account creation. ## 4. Ephemeral Key * **Temporary key** for limited operations. * Used for single or short-lived access (e.g., accessing a specific customer object). * Validity is configurable (see `[eph_key] validity` in `development.toml`). ## 5. JWT Key * **JWT Bearer Token** used for API authentication and session management. * Required for certain JWT-protected endpoints and user authentication flows. * Format: `Authorization: Bearer ` ### When to Use JWT tokens are primarily used by the Hyperswitch Control Center front end to authenticate API requests. You generally do **not** need to manage or use JWTs unless: * You’re building a **custom front end** that replaces the Control Center, or * You’re a developer **testing APIs directly** (e.g., using Postman or running the server without the UI). For most users interacting through the Control Center UI, JWTs are handled automatically and do not need to be generated or included manually. > **Note:**\ > JWTs are **not provisioned via the Hyperswitch dashboard**.\ > They are typically **issued during an authentication flow**, such as during login or session creation. ```http theme={null} Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` Keep your JWT tokens secure. Do not expose them in client-side code unless specifically required for session management, and always use HTTPS when transmitting JWTs. ## Reference Table | Key Type | Example Prefix | Usage | Security | | - | - | - | - | | Secret (API Key) | snd\_c69\*\*\*, prod\_\*\*\* | Backend server API requests | Keep secret | | Admin API Key | (admin-specific) | Admin operations | Highly confidential | | Publishable Key | pk\_snd\_3b3\*\*\* | Client-side, public usage | Safe to expose | | Ephemeral Key | (short-lived) | Temporary, limited access | Short validity, limited | | JWT Key | (JWT Bearer) | Session/user authentication | Control center calls |
Get your [API Key](https://app.hyperswitch.io/developers?tabIndex=1) and [Publishable Key](https://app.hyperswitch.io/home) from the Hyperswitch dashboard. *** # Error Codes Source: https://api-reference.hyperswitch.io/essentials/error_codes Hyperswitch uses error codes, types, and messages to communicate errors during API calls. There are two main types of error codes: Error Codes and Unified Error Codes. 1. **Error Codes** refer to the error code sent by the connector. 2. **Unified Error Codes** refer to the generic error code sent by the Hyperswitch server, based on the connector's error code. Hyperswitch groups the different error codes from connectors into more generic Unified Error Codes for structured relay of PSP errors, helping merchants derive patterns and determine the next steps for ongoing transactions. There are four types of Error Codes and five types of Unified Error Codes. **1. Error Codes:** The section below contains all the error codes and their corresponding error messages. | Error Code | Type | Description | | - | - | - | | IR | Invalid Request Error | Error caused due to invalid fields and values in API request | | CE | Connector Error | Errors originating from connector’s end | | HE | Hyperswitch Error | Errors originating from Hyperswitch’s end | | WE | Webhook Error | Errors related to Webhooks | | Error Codes | HTTP Status codes | Error Type | Error message | Error Handling | | - | - | - | - | - | | IR\_00 | 501 | server\_not\_available | This API is under development and will be made available soon | No action required. If you require this feature, please reach out to Hyperswitch support | | IR\_01 | 401 | invalid\_request\_error | API key not provided or invalid API key used. Provide the API key in the Authorization header using api-key (e.g api-key: API\_KEY) or create a new API key from the dashboard | Provide the API key in the Authorization header using api-key (e.g api-key: API\_KEY) or create a new API key from the dashboard | | IR\_02 | 404 | invalid\_request\_error | Unrecognized request URL | Please recheck and enter the correct request URL. Refer to our API documentation | | IR\_03 | 405 | invalid\_request\_error | The HTTP method is not applicable for this API | Please recheck the HTTP method used in the request. Refer to our API documentation | | IR\_04 | 400 | invalid\_request\_error | Missing required param: “field\_name” | Please pass the missing required parameter. Refer to our API documentation | | IR\_05 | 422 | invalid\_request\_error | “field\_name” contains invalid data. Expected format is “expected\_format” | Please pass the data in the expected format. Refer to our API documentation | | IR\_06 | 400 | invalid\_request\_error | “message” | Refer to our API documentation for required fields and format | | IR\_07 | 400 | invalid\_request\_error | Invalid value provided: “field\_name” | Provide a valid value for the required fields in the expected format. Refer to our API documentation | | IR\_08 | 400 | invalid\_request\_error | Client secret was not provided | Provide the client secret received in payments/create API response | | IR\_09 | 400 | invalid\_request\_error | The client\_secret provided does not match the client\_secret associated with the Payment | Provide the same client secret received in payments/create API response for the corresponding payment | | IR\_10 | 400 | invalid\_request\_error | Customer has an existing mandate/subscription | Cancel the active mandates/subscriptions for the customer before proceeding to delete the customer data | | IR\_11 | 400 | invalid\_request\_error | Customer has already been redacted | Customer has already been redacted. No action required | | IR\_12 | 400 | invalid\_request\_error | Reached the maximum refund attempts | Maximum refund attempts reached for this payment. Please contact Hyperswitch support for attempting more refunds for the same payment | | IR\_13 | 400 | invalid\_request\_error | Refund amount exceeds the payment amount | Please verify and pass a refund amount equal to or less than the payment amount | | IR\_14 | 400 | invalid\_request\_error | This Payment could not be “current\_flow” because it has a “field\_name” of “current\_value”. The expected state is “states” | Please verify the status of the payment and make sure that you are performing an action that is allowed for the current status of the payment | | IR\_15 | 400 | invalid\_request\_error | Invalid Ephemeral Key for the customer | Please pass the right Ephemeral key for the customer | | IR\_16 | 400 | invalid\_request\_error | “message” | Typically used when information involving multiple fields or previously provided information doesn’t satisfy a condition. Refer to our API documentation for required fields and format | | IR\_17 | 401 | invalid\_request\_error | Access forbidden, an invalid JWT token was used | Provide a valid JWT token to access the APIs | | IR\_18 | 401 | invalid\_request\_error | "message" | The user is not authorised to update the customer, Contact Org. Admin for the appropriate access. | | IR\_19 | 400 | invalid\_request\_error | "message" | Please check and retry with correct details. Refer to our API documentation | | IR\_20 | 400 | invalid\_request\_error | "flow" not supported by the "connector" | Requested flow is not supported for this Connector. | | IR\_21 | 400 | invalid\_request\_error | Missing required params | Please add the required params in the request. Refer to our API documentation | | IR\_22 | 403 | invalid\_request\_error | Access forbidden. Not authorized to access this "resource" | Contact Org. Admin for the appropriate access. | | IR\_23 | 400 | invalid\_request\_error | "message" | Use a supported file provider. Refer to our API documentation | | IR\_24 | 422 | processing\_error | Invalid "wallet\_name" wallet token | Share the correct wallet token. | | IR\_25 | 400 | invalid\_request\_error | Cannot delete the default payment method | Check if the Payment method is activated. Refer to Control centre to check this. | | IR\_26 | 400 | invalid\_request\_error | Invalid Cookie | Recheck the site setting for the cookies. | | IR\_27 | 404 | invalid\_request\_error | Extended card info does not exist | Recheck the card info shared in the request. | | IR\_28 | 400 | invalid\_request\_error | "message" | Use a valid currency. Refer to our API documentation | | IR\_29 | 422 | invalid\_request\_error | "message" | The data format is invalid for this request. Refer to our API documentation | | IR\_30 | 400 | invalid\_request\_error | Merchant connector account is configured with invalid config | Correct the config for merchant connector account | | IR\_31 | 400 | invalid\_request\_error | Card with the provided iin does not exist | Check the IIN (Issuer Identification Number) and ensure it is correct. | | IR\_32 | 400 | invalid\_request\_error | The provided card IIN length is invalid, please provide an iin with 6 or 8 digits | Provide a valid IIN with either 6 or 8 digits. | | IR\_33 | 400 | invalid\_request\_error | File not found / valid in the request | Ensure the required file is included in the request and is valid. Refer to our API documentation | | IR\_34 | 400 | invalid\_request\_error | Dispute id not found in the request | Ensure that a valid dispute ID is included in the request. | | IR\_35 | 400 | invalid\_request\_error | File purpose not found in the request or is invalid | Specify a valid file purpose in the request. | | IR\_36 | 400 | invalid\_request\_error | File content type not found / valid | Ensure the file content type is specified and is valid. | | IR\_37 | 404 | invalid\_request\_error | "message" | Check the request for the resource being accessed and ensure it exists. | | IR\_38 | 400 | invalid\_request\_error | "message" | Check for any duplicate entries in the request and correct them. | | IR\_39 | 400 | invalid\_request\_error | required payment method is not configured or configured incorrectly for all configured connectors | Verify that the required payment method is correctly configured for all connectors in use. | | CE\_00 | Status codes shared by the connectors | connector\_error | “message” | The error code and message passed from the connectors. Refer to the respective connector’s documentation for more information on the error | | CE\_01 | 400 | processing\_error | Payment failed during authorization with the connector. Retry payment | Retry the payment again as payment failed at the connector during authorization | | CE\_02 | 400 | processing\_error | Payment failed during authentication with the connector. Retry payment | Retry the payment again as payment failed at the connector during authentication | | CE\_03 | 400 | processing\_error | Capture attempt failed while processing with the connector | Capture failed for the payment at the connector. Please retry the payment | | CE\_04 | 400 | processing\_error | The card data is invalid | Invalid card data passed. Please pass valid card data | | CE\_05 | 400 | processing\_error | The card has expired | Card expired. Please pass valid card data | | CE\_06 | 400 | processing\_error | Refund failed while processing with the connector. Retry refund | Refund failed to process at the connector. Please retry refund | | CE\_07 | 400 | processing\_error | Verification failed while processing with the connector. Retry operation | Retry the operation again as verification failed at the connector | | CE\_08 | 400 | processing\_error | Dispute operation failed while processing with connector. Retry operation | Retry the operation again as dispute failed at the connector | | CE\_09 | 400 | invalid\_request\_error | Payout validation failed | Retry the operation again with correct Payout details. | | HE\_00 | 422,500 | server\_not\_available | Resource not available right now, Please try again later. | Please Wait for a few moments and try again. If the error still persists, please reach out to Hyperswitch support | | HE\_01 | 400,422 | duplicate\_request | Requested operation(Customer, Payments, Merchants, Refunds etc.) for these identifier already exists. | Please verify the Details(Customer, Payments, Merchants, Refunds, as applicable on the basis of request) and enter valid details. | | HE\_02 | 404 | object\_not\_found | Requested object(Customer, Payments, Merchants, Refunds etc.) does not exist in our records | Please verify the Details(Customer, Payments, Merchants, Refunds, as applicable on the basis of request) and enter valid details. | | HE\_03 | 500 | validation\_error | Validation Failed for the requested operation with the given details. | Please verify the details again and enter valid details | | HE\_04 | 404 | object\_not\_found | Requested object(Customer, Payments, Merchants, Refunds etc.) does not exist in our records | Please verify the Details(Customer, Payments, Merchants, Refunds, as applicable on the basis of request) and enter valid details. | | HE\_05 | 500 | processing\_error | Missing or invalid tenant details. | Please verify the tenant Details and try again. | | WE\_01 | 400 | invalid\_request\_error | Failed to authenticate the webhook | Please verify the authentication credentials and try again. | | WE\_02 | 400 | invalid\_request\_error | Bad request received in webhook | Check the request parameters and format, then try again. | | WE\_03 | 500 | router\_error | There was some issue processing the webhook | Please try again later. If the issue persists, contact Hyperswitch support. | | WE\_04 | 404 | object\_not\_found | Webhook resource not found | Ensure the webhook URL is correct and the resource exists. | | WE\_05 | 400 | invalid\_request\_error | Unable to process the webhook body | Ensure the webhook body is correctly formatted and try again. | | WE\_06 | 400 | invalid\_request\_error | Merchant Secret set by merchant for webhook source verification is invalid | Verify the Merchant Secret, then try again. | **2. Unified Error codes:** The section below contains all the unified error codes and their corresponding error messages. | Unified Error Code | Unified Error Categorisation | Unified Error message | | - | - | - | | UE\_1000 | Customer Error | Issue with payment method details. | | UE\_2000 | Connector Declines | Issue with Configurations. | | UE\_3000 | Connector Error | Technical issue with PSP. | | UE\_4000 | Integration Error | Issue in the integration. | | UE\_9000 | Others | Something went wrong. | ## Error Details Structure Hyperswitch returns a structured `error_details` object for failed payments. This object combines error information from the connector (PSP), the issuer (bank), and Hyperswitch's own interpretation. **Unified Details** This section is Hyperswitch's understanding of the failure. It is created by looking at the issuer and connector error signals and mapping them to a standard meaning. * **Category** - The high-level unified error code (for example `UE_1000` for payment method issues). * **Message** - High level unified error message that is consistent across different connectors. * **Standardised Code** - Code that identifies the specific cause for a failure within a broader error category such as `INVALID_EXPIRY_DATE`. * **Description** - A detailed description of the error intended for debugging, analytics, and support teams. * **User Guidance Message** - A user-friendly message that can be safely displayed to the customer. This message provides guidance on what the user should do to resolve the issue. * **Recommended Action** - A field that tells merchants what action to take after a payment failure. | Action | Description | | - | - | | `do_not_retry` | Never retry with same card | | `retry_later` | Retry after some time | | `retry_after_1_hour` | Retry after 1 hour | | `retry_after_24_hours` | Retry after 24 hours | | `retry_after_2_days` | Retry after 2 days | | `retry_after_4_days` | Retry after 4 days | | `retry_after_6_days` | Retry after 6 days | | `retry_after_8_days` | Retry after 8 days | | `retry_after_10_days` | Retry after 10 days | | `retry_after_instrument_update` | Retry after updating payment details | | `retry_with_different_payment_method_data` | Use different payment method | | `stop_recurring` | Stop recurring payments | ## Enhanced Errors This table provides a standardized mapping that translates granular payment error into consistent standardised codes, customer-facing messages and description. The classification mappings, user guidance message and descriptions are subject to change at any time. | Standardised Code | Unified Code(Category) | Unified Message(Message) | User Guidance Message | Description | | - | - | - | - | - | | **PAYMENT\_METHOD\_ISSUE** | **UE\_1000** | **Issue with payment method details** | **Issue with Payment Method details** | **Issue with Payment Method details** | | INVALID\_CARD\_NUMBER | UE\_1000 | Issue with payment method details | The card number doesn't look right. Please check it and try again | The card number is invalid | | INVALID\_EXPIRY\_DATE | UE\_1000 | Issue with payment method details | The card's expiry date seems incorrect or has passed. Update it or use another card. | Expiry date is in the past or improperly formatted. | | INVALID\_CVV | UE\_1000 | Issue with payment method details | The security code (CVV) is incorrect. Please re-enter it. | CVV is missing, malformed, or does not match issuer records | | PM\_ADDRESS\_MISMATCH | UE\_1000 | Issue with payment method details | The billing address doesn't match what the bank has on file. Update it or use another card. | Address mismatch (AVS failed) | | INSUFFICIENT\_FUNDS | UE\_1000 | Issue with payment method details | There aren't enough funds on this card. Use another card or add funds and try again | The entered card has insufficient funds | | CREDIT\_LIMIT\_EXCEEDED | UE\_1000 | Issue with payment method details | This card has reached its credit limit. Use another card or contact your bank. | Transaction exceeds cardholder's credit limit | | VELOCITY\_LIMIT\_EXCEEDED | UE\_1000 | Issue with payment method details | This card has hit a usage limit set by your bank. Try another card or contact your bank. | Transaction exceeds allowed frequency or velocity | | CARD\_LOST\_OR\_STOLEN | UE\_1000 | Issue with payment method details | The bank has blocked this card. Please use a different card. | This card has been reported as lost or stolen | | CARD\_NOT\_SUPPORTED\_RESTRICTED | UE\_1000 | Issue with payment method details | This card can't be used for this payment. Try another card or payment method. | Card is restricted for this merchant, channel, or use case | | ACCOUNT\_CLOSED\_OR\_INVALID | UE\_1000 | Issue with payment method details | This account is not active. Use a different payment method. | Account closed or invalid or missing | | AUTHORIZATION\_MISSING\_OR\_REVOKED | UE\_1000 | Issue with payment method details | This payment can't be completed because the prior authorization was canceled. Try another card or contact your bank. | Customer authorization is missing or was revoked | | INCORRECT\_AUTHENTICATION\_CODE | UE\_1000 | Issue with payment method details | The code you entered is incorrect. Request a new code and try again. | Incorrect authentication or verification code provided | | PAYMENT\_SESSION\_TIMEOUT | UE\_1000 | Issue with payment method details | Your session expired. Start the payment again. | Payment session expired before completion | | AUTHENTICATION\_FAILED | UE\_1000 | Issue with payment method details | We couldn't verify this payment with your bank. Try again or use a different payment method. | Authentication failed or was declined | | PAYMENT\_CANCELLED\_BY\_USER | UE\_1000 | Issue with payment method details | The payment was canceled. If this wasn't intended, please start a new payment. | Payment flow was canceled by user or system | | TRANSACTION\_NOT\_PERMITTED | UE\_1000 | Issue with payment method details | This payment method can't be used for this type of purchase. Try another payment method. | This type of purchase is not permitted or supported | | PM\_TOKENISATION\_ISSUE | UE\_1000 | Issue with payment method details | We couldn't save or use this card securely. Try again or use a different payment method. | Failed to tokenize or validate card credentials | | **CONFIGURATION\_ISSUE** | **UE\_2000** | **Issue with configuration** | **Something went wrong. Try another Payment Method** | **Issue with Configurations** | | MERCHANT\_INACTIVE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Merchant configuration inactive or invalid | | CFG\_PM\_NOT\_ENABLED\_OR\_MISCONFIGURED | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Payment method not enabled for this merchant | | CURRENCY\_OR\_CORRIDOR\_NOT\_ENABLED | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Currency or corridor not enabled | | WALLET\_OR\_TOKEN\_CONFIG\_ISSUE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Wallet or token configuration missing or incorrect | | STORED\_CREDENTIAL\_OR\_MIT\_NOT\_ENABLED | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Stored credential or MIT not enabled | | THREEDS\_CONFIGURATION\_ISSUE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | 3DS not enabled or improperly integrated. | | SUBSCRIPTION\_PLAN\_INACTIVE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Attempted charge on inactive or expired subscription | | **DOWNSTREAM\_TECHNICAL\_ISSUE** | **UE\_3000** | **Technical Issue with PSP** | **Something went wrong. Try again or contact your bank** | **Downstream technical issue** | | ISSUER\_UNAVAILABLE | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | The card issuer's bank is temporarily unavailable | | TRANSACTION\_TIMEDOUT | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Issuer timeout | | DO\_NOT\_HONOR | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Do not honor | | SUSPECTED\_FRAUD | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Issuer flagged as suspected fraud. | | PSP\_FRAUD\_ENGINE\_DECLINE | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Declined by PSP fraud engine | | COMPLIANCE\_OR\_SANCTIONS\_RESTRICTION | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Sanctions or compliance blockage | | PSP\_ACQUIRER\_ERROR | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Temporary acquirer internal error | | THREEDS\_AUTHENTICATION\_SERVICE\_ISSUE | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | 3DS Authentication Service Failure | | AUTHENTICATION\_REQUIRED | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Authentication is required | | **INTEGRATION\_ISSUE** | **UE\_4000** | **Issue with integration** | **Something went wrong. Try another payment method or contact your bank** | **Issue with Integration** | | MISSING\_OR\_INVALID\_PARAM | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Missing or invalid parameter | | INVALID\_CREDENTIALS | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Invalid credentials | | OPERATION\_NOT\_ALLOWED | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Operation not allowed | | DUPLICATE\_REQUEST | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Duplicate or Idempotent request | | INVALID\_STATE | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Invalid state of operation | | THREEDS\_DATA\_OR\_PROTOCOL\_INVALID | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | 3DS payload invalid or inconsistent | | RATE\_LIMIT | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | API rate limit exceeded | | INTEG\_CRYPTOGRAPHIC\_ISSUE | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Token or cryptographic integration issue | | **GEN\_UNKNOWN\_ERROR** | **UE\_9000** | **Something went wrong** | **Something went wrong** | **Something went wrong** | # Go-live Checklist Source: https://api-reference.hyperswitch.io/essentials/go-live Refer to this checklist for a seamless transition as you prepare to go live with your integration. The connector configurations set up in the sandbox need to be replicated on the Hyperswitch production account. ### Signing of Hyperswitch services agreement * [ ] Ensure that the Hyperswitch services agreement is signed and shared with the Hyperswitch team. In case you need any help, please drop an email to [biz@hyperswitch.io](mailto:biz@hyperswitch.io). The Hyperswitch team will share your production Hyperswitch credentials once the above process is completed. ### Connector Configurations * [ ] Configure all the required connectors using production credentials on the Hyperswitch production dashboard and enable the required payment methods. * [ ] Ensure that the payment methods are enabled on the connector (payment processor) dashboard. * [ ] Enable raw card processing for each connector. Some connectors offer this as a dashboard toggle feature. Some processors might need you to share a PCI Attestation of Compliance over email to enable this. Drop an email to [biz@hyperswitch.io](mailto:biz@hyperswitch.io) if you need any support with PCI AOC. ### Secure your api-keys * [ ] Make sure your secret key (api-key) is not exposed on the front-end (website/mobile app). * [ ] Ensure that your workflow avoids the duplication or storage of your API keys in multiple locations. ### Set up Webhooks * [ ] [Configure your webhook endpoint](https://juspay-78.mintlify.app/essentials/webhooks#configuring-webhooks) on our dashboard to receive notifications for different events. * [ ] Update Hyperswitch's webhook endpoints on your connector's Dashboard. [Refer here](https://juspay-78.mintlify.app/essentials/webhooks#configuring-webhooks) for detailed instructions. * [ ] Update the connector secret key in our dashboard for us to authenticate webhooks sent by your connector. ### Secure your Payments * [ ] Make sure you decrypt and verify the signed payload sent along with the payment status in your return URL. * [ ] Always verify the payment amount and payment status before fulfilling your customer's shopping cart/service request. ### Error Handling * [ ] Make sure your API integration is set up to handle all the possible error scenarios (refer this [link](https://juspay-78.mintlify.app/essentials/error_codes)). * [ ] Ensure your Unified Checkout (SDK) integration is set up to handle all the possible error scenarios (refer this [link](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/errorCodes)). * [ ] Ensure that your integration can handle the entire payments lifecycle and test various scenarios using actual payment details. ### Customize and sanity check the payment experience * [ ] Ensure the pay button is properly highlighted to the customer. * [ ] Ensure a blended look and feel of the payment experience using the [styling APIs](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/customization) of Unified Checkout. # Rate Limits Source: https://api-reference.hyperswitch.io/essentials/rate_limit The Hyperswitch API has multiple checks in place to enhance its stability when faced with sudden surges of incoming traffic. Merchants who send numerous requests in rapid succession could encounter error responses indicated by the status code 429. The default rate limit for all Hyperswitch APIs is **80 requests per second**. Reach out to [biz@hyperswitch.io](mailto:biz@hyperswitch.io) if you have a requirement for higher limits. ## How to handle rate limits Effectively handling rate limit 429 errors is crucial for maintaining a seamless user experience. * Implement retry mechanisms with progressively increasing intervals to avoid overwhelming the system with repeated requests. * To proactively manage these errors, monitoring tools can help track usage patterns and provide insights for adjusting rate limits as necessary. * Ultimately, a well-orchestrated strategy for managing 429 errors not only prevents disruption but also fosters positive user engagement by transparently addressing limitations and promoting responsible API usage. ## Understanding API locking If you see a 429 error with the following error message, it is due to API locking and not due to rate limiting: ```text theme={null} At this moment, access to this object is restricted due to ongoing utilization by another API request or an ongoing Hyperswitch process. Retry after some time if this error persists. ``` API locking is a robust feature that empowers us to proactively secure and optimize access to our APIs. Our API locks objects on some operations to prevent the disruption caused by concurrent workloads that could potentially lead to inconsistent outcomes. This proactive measure not only ensures the continued integrity and performance of our APIs but also guarantees a high standard of security for our users. Once triggered, the API lock initiates a controlled pause in access, preventing any potential threats from compromising the system. # 👋 Welcome to Hyperswitch API Reference Source: https://api-reference.hyperswitch.io/introduction Hyperswitch provides a collection of APIs that enable you to process and manage payments. Our APIs accept and return JSON in the HTTP body and return standard HTTP response codes. You can consume the APIs directly using your favorite HTTP/REST library. Create your first payment using Hyperswitch APIs. Discover how to process one-time and recurring payments, save payment methods, and more. Save customer payment methods securely for future transactions Host Hyperswitch on-premise? Utilize our full API suite. ## Environment We have a testing environment referred to "sandbox," which you can set up to test API calls without affecting production data. You can sign up on our Dashboard to get API keys to access Hyperswitch API. Use the following base URLs when making requests to the APIs: | Environment | Base URL | | - | - | | Sandbox | [https://sandbox.hyperswitch.io](https://sandbox.hyperswitch.io) | | Production | [https://api.hyperswitch.io](https://api.hyperswitch.io) | If you **do not hold a PCI certification** to collect and store card data on your servers, we recommend using [**Unified Checkout**](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/#unified-checkout) to accept card information from users. ## Authentication and API keys Hyperswitch authenticates your API requests using your account’s API keys. Each account has two API keys for authentication: | Key | Example | When to Use | | - | - | - | | Secret key (API-key) | `snd_c69***` | Used to authenticate API requests from your merchant server. **Don’t expose this key** on a website or embed it in a mobile application. | | Publishable key | `pk_snd_3b3***` | Used to authenticate API requests from your app’s client. Can be publicly-accessible in your web or mobile app’s client-side code. | Get your [API key](https://app.hyperswitch.io/developers?tabIndex=1) and [Publishable Key](https://app.hyperswitch.io/home) [Postman Collection](https://www.postman.com/hyperswitch/workspace/hyperswitch-development/collection/25176162-630b5353-7002-44d1-8ba1-ead6c230f2e3) ## Payment Status Lifecycle Hyperswitch handles the complex functionality of a comprehensive payments flow through the Payments object that transitions through multiple states during its payments lifecycle. Given below are the various statuses a payment can have: | Payment Status | Description | | - | - | | requires\_payment\_method | Once you create a payment through payments/create endpoint with no payment method attached to it, the payments object transitions to ‘requires\_payment\_method’. | | requires\_confirmation | After attaching a payment method through payments/update endpoint, the payments object requires you to confirm the payment. | | requires\_customer\_action | Once the payment is confirmed through payments/confirm endpoint, if additional authentication is required, the payments object transitions to this state. | | requires\_capture | If you want to do separate authorize and capture, setting capture field to ‘manual’ during payments/create or confirm call will transition the payment object to this state after customer action succeeds. | | processing | In case of automatic capture, the payments object transitions to processing state post confirm call and subsequent customer authentication if available. | | succeeded | The payments object reaches success state post confirmation of successful processing from the payment processor. | | failed | The payments object transitions to a failed state when the payment processor confirms the processing failure. | ## Payment Lifecycle - more payment states | Payment Status | Description | | - | - | | Merchant Action Required | The payment is waiting on some action from the merchant (e.g., manual fraud approval) | | Partially Captured | The payment has been captured partially, and the remaining amount cannot be captured | | Partially Captured and Capturable | The payment has been captured partially and the remaining amount is capturable | | Partially Authorized and Requires Capture | The payment has been authorized for a partial amount and requires capture | | Conflicted | There has been a discrepancy between the amount/currency sent in the request and the amount/currency received by the processor. Applicable for Crypto payments and Bank transfer payments (EU) where user can change the amount on Bank page | | Expired | The payment expired before it could be captured | ## Redirect URL This is what a url looks like after redirection `https://app.hyperswitch.io?status=succeeded&payment_intent_client_secret=pay_NCv9vc19f8aa75OpFxH8_secret_V4zAc7V0C8WAw6FECMKM&amount=10000&manual_retry_allowed=false&signature=4fae0cfa775e4551db9356563d4b98b55662fe3c1c945fe215d90ccf3541282c535909ae901d82174d6b1e46ba1684aa0aa4c8861be0e2a9ef6f950a975d5014&signature_algorithm=HMAC-SHA512` The available parameters are as follows: * **status** - can have values of `succeeded`, `processing`and `failed`. * **payment\_intent\_client\_secret** - This is the client secret associated with the payment. This can be used to retrieve the payment status from hyperswitch. * **manual\_retry\_allowed** - whether this payment can be retried or not. * **signature** - A HMAC signature of the payload, this can be verified using the `payment_response_hash_key`. * **signature\_algorithm** - The HMAC algorithm used to calculate the signature. # Authentication - Create Source: https://api-reference.hyperswitch.io/v1/authentication/authentication--create post /authentication Create a new authentication for accessing our APIs from your servers. # Authentication - GET Eligibility Check Source: https://api-reference.hyperswitch.io/v1/authentication/authentication--get-eligibility-check get /authentication/{authentication_id}/eligibility-check # Authentication - POST Eligibility Check Source: https://api-reference.hyperswitch.io/v1/authentication/authentication--post-eligibility-check post /authentication/{authentication_id}/eligibility-check # Profile - Create Source: https://api-reference.hyperswitch.io/v1/business-profile/business-profile--create post /account/{account_id}/business_profile Creates a new *profile* for a merchant # Profile - Update Source: https://api-reference.hyperswitch.io/v1/business-profile/business-profile--update post /account/{account_id}/business_profile/{profile_id} Update the *profile* # Payment Method - Set Default Payment Method for Customer Source: https://api-reference.hyperswitch.io/v1/customer-set-default-payment-method/customers--set-default-payment-method post /{customer_id}/payment_methods/{payment_method_id}/default Set the Payment Method as Default for the Customer. # Customers - Create Source: https://api-reference.hyperswitch.io/v1/customers/customers--create post /customers Creates a customer object and stores the customer details to be reused for future payments. Incase the customer already exists in the system, this API will respond with the customer details. # Customers - Delete Source: https://api-reference.hyperswitch.io/v1/customers/customers--delete delete /customers/{customer_id} Delete a customer record. # Customers - List Source: https://api-reference.hyperswitch.io/v1/customers/customers--list get /customers/list Lists all the customers for a particular merchant id. # Customers - Retrieve Source: https://api-reference.hyperswitch.io/v1/customers/customers--retrieve get /customers/{customer_id} Retrieves a customer's details. # Customers - Retrieve using Merchant Reference ID Source: https://api-reference.hyperswitch.io/v1/customers/customers--retrieve-by-merchant-reference-id get /v1/customers/reference/{merchant_reference_id} Retrieves a customer's details using the merchant supplied reference ID. # Customers - Update Source: https://api-reference.hyperswitch.io/v1/customers/customers--update post /customers/{customer_id} Updates the customer's details in a customer object. # Disputes - Accept Dispute Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--accept post /disputes/accept/{dispute_id} Accepts a dispute # Disputes - Attach Evidence to Dispute Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--attach-evidence put /disputes/evidence Attaches an uploaded evidence file to a dispute # Disputes - Delete Evidence attached to a Dispute Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--delete-evidence delete /disputes/evidence Deletes an evidence file attached to a dispute # Disputes - Get Disputes Aggregate Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--get-aggregate get /disputes/aggregate Gets a count of disputes grouped by their status for a merchant within a time range # Disputes - Get Disputes Aggregate for Profiles Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--get-aggregate-profiles get /disputes/profile/aggregate Gets a count of disputes grouped by their status for the given profiles within a time range # Disputes - Disputes Filters Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--get-filters get /disputes/filter Lists all the filters associated with disputes # Disputes - Disputes Filters Profile Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--get-filters-profiles get /disputes/profile/filter Lists all the filters associated with disputes for the given profiles # Disputes - List Disputes Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--list get /disputes/list Lists all the Disputes for a merchant # Disputes - List Disputes for The Given Profiles Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--list-profiles get /disputes/profile/list Lists all the Disputes for a merchant # Disputes - Retrieve Dispute Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--retrieve get /disputes/{dispute_id} Retrieves a dispute # Disputes - Retrieve Dispute Evidence Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--retrieve-evidence get /disputes/evidence/{dispute_id} Retrieves evidence for a dispute # Disputes - Uploads Dispute Evidence Source: https://api-reference.hyperswitch.io/v1/disputes/disputes--submit-evidence post /disputes/evidence Uploads evidence for a dispute # Mandates customer mandates list Source: https://api-reference.hyperswitch.io/v1/mandates/mandates--customer-mandates-list post /customers/{customer_id}/mandates # Mandates - Retrieve Mandate Source: https://api-reference.hyperswitch.io/v1/mandates/mandates--retrieve-mandate get /mandates/{mandate_id} Retrieves a mandate created using the Payments/Create API # Mandates - Revoke Mandate Source: https://api-reference.hyperswitch.io/v1/mandates/mandates--revoke-mandate post /mandates/revoke/{mandate_id} Revokes a mandate created using the Payments/Create API # Merchant Account - Create Source: https://api-reference.hyperswitch.io/v1/merchant-account/merchant-account--create post /accounts Create a new account for a *merchant* and the *merchant* could be a seller or retailer or client who likes to receive and send payments. # Merchant Account - Delete Source: https://api-reference.hyperswitch.io/v1/merchant-account/merchant-account--delete delete /accounts/{account_id} Delete a *merchant* account # Merchant Account - KV Status Source: https://api-reference.hyperswitch.io/v1/merchant-account/merchant-account--kv-status post /accounts/{account_id}/kv Toggle KV mode for the Merchant Account # Merchant Account - Retrieve Source: https://api-reference.hyperswitch.io/v1/merchant-account/merchant-account--retrieve get /accounts/{account_id} Retrieve a *merchant* account details. # Merchant Account - Update Source: https://api-reference.hyperswitch.io/v1/merchant-account/merchant-account--update post /accounts/{account_id} Updates details of an existing merchant account. Helpful in updating merchant details such as email, contact details, or other configuration details like webhook, routing algorithm etc # Organization - Create Source: https://api-reference.hyperswitch.io/v1/organization/organization--create post /organization Create a new organization # Organization - Retrieve Source: https://api-reference.hyperswitch.io/v1/organization/organization--retrieve get /organization/{id} Retrieve an existing organization # Organization - Update Source: https://api-reference.hyperswitch.io/v1/organization/organization--update put /organization/{id} Create a new organization for . # List customer saved payment methods for a Payment Source: https://api-reference.hyperswitch.io/v1/payment-methods/list-customer-saved-payment-methods-for-a-payment get /customers/payment_methods Lists all the applicable payment methods for a particular payment tied to the `client_secret`. # List payment methods for a Customer Source: https://api-reference.hyperswitch.io/v1/payment-methods/list-payment-methods-for-a-customer get /customers/{customer_id}/payment_methods Lists all the applicable payment methods for a particular Customer ID. # List payment methods for a Merchant Source: https://api-reference.hyperswitch.io/v1/payment-methods/list-payment-methods-for-a-merchant get /account/payment_methods Lists the applicable payment methods for a particular Merchant ID. Use the client secret and publishable key authorization to list all relevant payment methods of the merchant for the payment corresponding to the client secret. # List payment methods for a Payment Source: https://api-reference.hyperswitch.io/v1/payment-methods/list-payment-methods-for-a-payment-via-client-sdk get /payments/{payment_id}/client Client SDK endpoint. Returns a unified response combining merchant-enabled payment methods and customer saved payment methods, filtered via Euclid constraint graph and session flow routing. Supported auth: - SDK auth via `Authorization`. - Publishable-key auth via `api-key: pk_...` and `client_secret` query param. - Merchant API-key auth via `api-key: `. # Payment Method - Delete Source: https://api-reference.hyperswitch.io/v1/payment-methods/payment-method--delete delete /payment_methods/{method_id} Deletes a payment method of a customer. # Payment Method - Retrieve Source: https://api-reference.hyperswitch.io/v1/payment-methods/payment-method--retrieve get /payment_methods/{method_id} Retrieves a payment method of a customer. # Payment Method - Set Default Payment Method for Customer Source: https://api-reference.hyperswitch.io/v1/payment-methods/payment-method--set-default-payment-method-for-customer post /{customer_id}/payment_methods/{payment_method_id}/default Set the Payment Method as Default for the Customer. # Payment Method - Update Source: https://api-reference.hyperswitch.io/v1/payment-methods/payment-method--update post /payment_methods/{method_id}/update Update an existing payment method of a customer. This API is useful for use cases such as updating the card number for expired cards to prevent discontinuity in recurring payments. # PaymentMethods - Create Source: https://api-reference.hyperswitch.io/v1/payment-methods/paymentmethods--create post /payment_methods Creates and stores a payment method against a customer. In case of cards, this API should be used only by PCI compliant merchants. # Payment flows Source: https://api-reference.hyperswitch.io/v1/payments/payment--flows Hyperswitch provides flexible payment processing with multiple flow patterns to accommodate different business needs. The system supports one-time payments, saved payment methods, and recurring billing through a comprehensive API design. ```mermaid theme={null} graph TD A["Payment Request"] --> B{"Payment Type"} B -->|One-time| C["One-time Payment Flows"] B -->|Save for Future| D["Payment Method Storage"] B -->|Recurring| E["Recurring Payment Flows"] C --> C1["Instant Payment"] C --> C2["Manual Capture"] C --> C3["Decoupled Flow"] C --> C4["3DS Authentication"] D --> D1["Save During Payment"] D --> D2["List Saved Methods"] E --> E1["Setup (CIT)"] E --> E2["Execute (MIT)"] ``` ## One-Time Payment Patterns ### 1. Instant Payment (Automatic Capture) **Use Case:** Simple, immediate payment processing **Endpoint:** `POST /payments` ```mermaid theme={null} sequenceDiagram participant Client participant Hyperswitch participant Processor Client->>Hyperswitch: POST /payments
{confirm: true, capture_method: "automatic"} Hyperswitch->>Processor: Authorize + Capture Processor-->>Hyperswitch: Payment Complete Hyperswitch-->>Client: Status: succeeded ``` **Required Fields:** * `confirm: true` * `capture_method: "automatic"` * `payment_method` **Final Status:** `succeeded` ### 2. Two-Step Manual Capture **Use Case:** Deferred settlement (e.g., ship before charging) ```mermaid theme={null} sequenceDiagram participant Client participant Hyperswitch participant Processor Client->>Hyperswitch: POST /payments
{confirm: true, capture_method: "manual"} Hyperswitch->>Processor: Authorize Only Processor-->>Hyperswitch: Authorization Hold Hyperswitch-->>Client: Status: requires_capture Note over Client: Ship goods, then capture Client->>Hyperswitch: POST /payments/{id}/capture Hyperswitch->>Processor: Capture Funds Processor-->>Hyperswitch: Capture Complete Hyperswitch-->>Client: Status: succeeded ``` **Flow:** 1. **Authorize:** `POST /payments` with `capture_method: "manual"` 2. **Status:** `requires_capture` 3. **Capture:** `POST /payments/{payment_id}/capture` 4. **Final Status:** `succeeded` ### 3. Fully Decoupled Flow **Use Case:** Complex checkout journeys with multiple modification steps. Useful in headless checkout or B2B portals where data is filled progressively. ```mermaid theme={null} sequenceDiagram participant Client participant Hyperswitch Client->>Hyperswitch: POST /payments
(Create Intent) Hyperswitch-->>Client: payment_id + client_secret Client->>Hyperswitch: POST /payments/{id}
(Update: customer, amount, etc.) Hyperswitch-->>Client: Updated Intent Client->>Hyperswitch: POST /payments/{id}/confirm
(Final Confirmation) Hyperswitch-->>Client: Status: succeeded/requires_capture opt Manual Capture Client->>Hyperswitch: POST /payments/{id}/capture Hyperswitch-->>Client: Status: succeeded end ``` **Endpoints:** * **Create:** `POST /payments` * **Update:** `POST /payments/{payment_id}` * **Confirm:** `POST /payments/{payment_id}/confirm` * **Capture:** `POST /payments/{payment_id}/capture` (if manual) ### 4. 3D Secure Authentication Flow **Use Case:** Enhanced security with customer authentication ```mermaid theme={null} sequenceDiagram participant Client participant Hyperswitch participant Customer participant Bank Client->>Hyperswitch: POST /payments
{authentication_type: "three_ds"} Hyperswitch-->>Client: Status: requires_customer_action
+ redirect_url Client->>Customer: Redirect to 3DS page Customer->>Bank: Complete 3DS Challenge Bank-->>Hyperswitch: Authentication Result Hyperswitch->>Hyperswitch: Resume Payment Processing Hyperswitch-->>Client: Status: succeeded ``` **Additional Fields:** * `authentication_type: "three_ds"` **Status Progression:** `processing` → `requires_customer_action` → `succeeded` ## Payment Method Management ### 1. Saving Payment Methods ```mermaid theme={null} graph LR A["Payment Request"] --> B["Add setup_future_usage"] B --> C{"Usage Type"} C -->|"off_session"| D["For Recurring/MIT"] C -->|"on_session"| E["For Customer-Present"] D --> F["payment_method_id Returned"] E --> F ``` **During Payment Creation:** * Add `setup_future_usage: "off_session"` or `"on_session"` * Include `customer_id` * **Result:** `payment_method_id` returned on success **Understanding `setup_future_usage`:** * **`on_session`**: Use when the customer is actively present during the transaction. This is typical for scenarios like saving card details for faster checkouts in subsequent sessions where the customer will still be present to initiate the payment (e.g., card vaulting for e-commerce sites). * **`off_session`**: Use when you intend to charge the customer later without their active involvement at the time of charge. This is suitable for subscriptions, recurring billing, or merchant-initiated transactions (MITs) where the customer has pre-authorized future charges. ### 2. Using Saved Payment Methods ```mermaid theme={null} sequenceDiagram participant Client participant Hyperswitch Client->>Hyperswitch: POST /payments/create
{customer_id} Hyperswitch-->>Client: client_secret Client->>Hyperswitch: GET /customers/payment_methods
{client_secret, publishable_key} Hyperswitch-->>Client: List of payment_tokens Client->>Hyperswitch: POST /payments/{id}/confirm
{payment_token} Hyperswitch-->>Client: Payment Result ``` **Steps:** 1. **Initiate:** Create payment with `customer_id` 2. **List:** Get saved cards via `GET /customers/payment_methods` 3. **Confirm:** Use selected `payment_token` in confirm call ### PCI Compliance and `payment_method_id` Storing `payment_method_id` (which is a token representing the actual payment instrument, which could be a payment token, network token, or payment processor token) significantly reduces your PCI DSS scope. Hyperswitch securely stores the sensitive card details and provides you with this token. While you still need to ensure your systems handle `payment_method_id` and related customer data securely, you avoid the complexities of storing raw card numbers. Always consult with a PCI QSA to understand your specific compliance obligations. ## Recurring Payment Flows ### 3. Customer-Initiated Transaction (CIT) Setup ```mermaid theme={null} graph TD A["CIT Setup"] --> B{"Setup Type"} B -->|"With Charge"| C["Amount > 0
setup_future_usage: off_session"] B -->|"Zero Dollar Auth"| D["Amount: 0
payment_type: setup_mandate"] C --> E["payment_method_id"] D --> E ``` **Option 1 - Setup with Charge:** * `setup_future_usage: "off_session"` * `amount > 0` **Option 2 - Zero Dollar Authorization:** * `setup_future_usage: "off_session"` * `amount: 0` * `payment_type: "setup_mandate"` ### 4. Merchant-Initiated Transaction (MIT) Execution ```mermaid theme={null} sequenceDiagram participant Merchant participant Hyperswitch participant Processor Note over Merchant: Subscription billing trigger Merchant->>Hyperswitch: POST /payments
{off_session: true, recurring_details} Hyperswitch->>Processor: Process with saved payment_method_id Processor-->>Hyperswitch: Payment Result Hyperswitch-->>Merchant: Status: succeeded ``` **Required Fields:** * `off_session: true` * `recurring_details: { "type": "payment_method_id", "data": ""}` **Use Case:** Subscription charges, scheduled billing without customer interaction ## Status Flow Summary ```mermaid theme={null} stateDiagram-v2 [*] --> RequiresConfirmation RequiresConfirmation --> Processing: confirm=true Processing --> RequiresCustomerAction: 3DS needed RequiresCustomerAction --> Processing: 3DS complete Processing --> RequiresCapture: manual capture Processing --> Succeeded: automatic capture RequiresCapture --> Succeeded: capture API call RequiresCapture --> PartiallyCaptured: partial capture PartiallyCaptured --> [*] Succeeded --> [*] Processing --> Failed: payment failed Failed --> [*] ``` ## Notes * **Terminal States:** `succeeded`, `failed`, `cancelled`, `partially_captured` are terminal states requiring no further action * **Capture Methods:** System supports `automatic` (funds captured immediately), `manual` (funds captured in a separate step), `manual_multiple` (funds captured in multiple partial amounts via separate steps), and `scheduled` (funds captured automatically at a future predefined time) capture methods. * **Authentication:** 3DS authentication automatically resumes payment processing after customer completion * **MIT Compliance:** Off-session recurring payments follow industry standards for merchant-initiated transactions # Payments - Cancel Source: https://api-reference.hyperswitch.io/v1/payments/payments--cancel post /payments/{payment_id}/cancel A Payment could can be cancelled when it is in one of these statuses: `requires_payment_method`, `requires_capture`, `requires_confirmation`, `requires_customer_action`. # Payments - Cancel Post Capture Source: https://api-reference.hyperswitch.io/v1/payments/payments--cancel-post-capture post /payments/{payment_id}/cancel_post_capture A Payment could can be cancelled when it is in one of these statuses: `succeeded`, `partially_captured`, `partially_captured_and_capturable`. # Payments - Cancel Post Capture Retrieve Source: https://api-reference.hyperswitch.io/v1/payments/payments--cancel-post-capture-retrieve get /payments/{payment_id}/cancel_post_capture Retrieves a canceled Payment post capture # Payments - Capture Source: https://api-reference.hyperswitch.io/v1/payments/payments--capture post /payments/{payment_id}/capture Captures the funds for a previously authorized payment intent where `capture_method` was set to `manual` and the payment is in a `requires_capture` state. Upon successful capture, the payment status usually transitions to `succeeded`. The `amount_to_capture` can be specified in the request body; it must be less than or equal to the payment's `amount_capturable`. If omitted, the full capturable amount is captured. A payment must be in a capturable state (e.g., `requires_capture`). Attempting to capture an already `succeeded` (and fully captured) payment or one in an invalid state will lead to an error. # Payments complete authorize Source: https://api-reference.hyperswitch.io/v1/payments/payments--complete-authorize post /{payment_id}/complete_authorize # Payments - Confirm Source: https://api-reference.hyperswitch.io/v1/payments/payments--confirm post /payments/{payment_id}/confirm Confirms a payment intent that was previously created with `confirm: false`. This action attempts to authorize the payment with the payment processor. Expected status transitions after confirmation: - `succeeded`: If authorization is successful and `capture_method` is `automatic`. - `requires_capture`: If authorization is successful and `capture_method` is `manual`. - `failed`: If authorization fails. # Payments - Create Source: https://api-reference.hyperswitch.io/v1/payments/payments--create post /payments Creates a payment resource, which represents a customer's intent to pay. This endpoint is the starting point for various payment flows: Use the dropdown on the top right corner of the code snippet to try out different payment scenarios. # Payments - Extended Authorization Source: https://api-reference.hyperswitch.io/v1/payments/payments--extend-authorization post /payments/{payment_id}/extend_authorization Extended authorization is available for payments currently in the `requires_capture` status Call this endpoint to increase the authorization validity period # Payments - External 3DS Authentication Source: https://api-reference.hyperswitch.io/v1/payments/payments--external-3ds-authentication post /payments/{payment_id}/3ds/authentication External 3DS Authentication is performed and returns the AuthenticationResponse # Payments - Incremental Authorization Source: https://api-reference.hyperswitch.io/v1/payments/payments--incremental-authorization post /payments/{payment_id}/incremental_authorization Authorized amount for a payment can be incremented if it is in status: requires_capture # Payments - List Source: https://api-reference.hyperswitch.io/v1/payments/payments--list get /payments/list To list the *payments* # Payments - Retrieve Source: https://api-reference.hyperswitch.io/v1/payments/payments--retrieve get /payments/{payment_id} Retrieves a Payment. This API can also be used to get the status of a previously initiated payment or next action for an ongoing payment # Payments - Session token Source: https://api-reference.hyperswitch.io/v1/payments/payments--session-token post /payments/session_tokens Creates a session object or a session token for wallets like Apple Pay, Google Pay, etc. These tokens are used by Hyperswitch's SDK to initiate these wallets' SDK. # Payments - Submit Eligibility Data Source: https://api-reference.hyperswitch.io/v1/payments/payments--submit-eligibility-data post /payments/{payment_id}/eligibility Runs eligibility checks (blocklist, card testing guard) and calculates an external surcharge in a single call. Intended to be called by the SDK before the final confirm step. - If eligibility is denied the response will contain `sdk_next_action: deny` and no surcharge details. - If the merchant has no surcharge connector configured, `surcharge_details` will be `null`. - Surcharge calculation is best-effort: if the external call fails the payment still proceeds with `surcharge_details: null`. # Payments - Update Source: https://api-reference.hyperswitch.io/v1/payments/payments--update post /payments/{payment_id} To update the properties of a *PaymentIntent* object. This may include attaching a payment method, or attaching customer object or metadata fields after the Payment is created # Payments - Update Metadata Source: https://api-reference.hyperswitch.io/v1/payments/payments--update-metadata post /payments/{payment_id}/update_metadata # Payments Link - Retrieve Source: https://api-reference.hyperswitch.io/v1/payments/payments-link--retrieve get /payment_link/{payment_link_id} To retrieve the properties of a Payment Link. This may be used to get the status of a previously initiated payment or next action for an ongoing payment # Setup instructions Source: https://api-reference.hyperswitch.io/v1/payments/setup--instructions The **Hyperswitch Payments API** enables businesses to **accept, process, and manage payments seamlessly**. It supports the entire **payment lifecycle**—from creation to capture, refunds, and disputes—allowing smooth integration of **various payment methods** into any application with minimal complexity. ### How to try your first payment through hyperswitch? You have two options to use the Payments API: 1. **Sandbox API Key (Dashboard)** – Quick testing without setup. 2. **Self-Deploy** – Create merchants and API keys through Rest API. Each option has specific nuances, we have mentioned the differences in the below step by step guide We recommend using our [Dashboard](https://app.hyperswitch.io/dashboard/login) to generate API Key and setting up Connectors (Step 4) for faster trial and simple setup. This account is representative of you or your organization that would like to accept payments from different payment connectors Access the [Dashboard](https://app.hyperswitch.io/dashboard/login) and sign up -> **Sign up here is equivalent to creating a Merchant Account** Use the admin api key and the [Merchant Account - Create](api-reference/merchant-account/merchant-account--create) endpoint to create your Merchant Account You can now generate an API key that will be the secret key used to authenticate your payment request In Dashboard go to Developer-> API Keys -> +Create New Api Key. This key can be used in your API requests for authentication. Use the admin api key and the [Merchant Account - Create](api-reference/merchant-account/merchant-account--create) endpoint to create your Merchant Account Connect the payment [connectors](api-reference/merchant-connector-account/merchant-connector--create) and payment methods that your organization will accept. Connectors could be a payment processor/facilitator/acquirer or a provider of specialized services like Fraud/Accounting In Dashboard go to Connectors -> +Connect a Dummy Processor. Choose the payments methods to enable and complete setup. Use the admin api key and the [Connector Account](api-reference/merchant-connector-account/merchant-connector--create) endpoints to set up a connector You are all set! Go ahead and try the [Payments API](api-reference/payments/payments--create), be sure to try the different use cases provided Test the use cases you are interested in and in case of difficulty, feel free to contact us on our [slack channel](https://join.slack.com/t/hyperswitch-io/shared_invite/zt-2jqxmpsbm-WXUENx022HjNEy~Ark7Orw) # Payouts - Cancel Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--cancel post /payouts/{payout_id}/cancel # Payouts - Confirm Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--confirm post /payouts/{payout_id}/confirm # Payouts - Create Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--create post /payouts/create Create a payout with `payout_method_data` (including raw card details) or a saved `payout_method_id`. ## External-vault card payouts Use a card saved during a payment. Provide a unique `payout_id`, the saved `payout_method_id`, and the card owner's `customer_id` or `customer.id`. Set `confirm=true`, `auto_fulfill=true`, `payout_type=card`, and `recurring=false`. These values apply when omitted for external-vault payouts. Send the request from your server; no separate confirmation call is required. For this flow, use the saved `payout_method_id` instead of inline `payout_method_data`. Do not send vault tokens or credentials. ## Retry handling After a timeout, retrieve the payout using its `payout_id` before submitting another request. Do not create a new payout ID to retry the same payout. Creating a payout with an existing `payout_id` returns a duplicate-payout error. Use `merchant_order_reference_id` for reconciliation, not retry protection. # Payouts - List using filters Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--filter post /payouts/list # Payouts - Fulfill Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--fulfill post /payouts/{payout_id}/fulfill # Payouts - List Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--list get /payouts/list # Payouts - List available filters Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--list-filters post /payouts/filter # Payouts - Retrieve Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--retrieve get /payouts/{payout_id} # Payouts - Update Source: https://api-reference.hyperswitch.io/v1/payouts/payouts--update post /payouts/{payout_id} # Refunds - Create Source: https://api-reference.hyperswitch.io/v1/refunds/refunds--create post /refunds Creates a refund against an already processed payment. In case of some processors, you can even opt to refund only a partial amount multiple times until the original charge amount has been refunded # Refunds - List Source: https://api-reference.hyperswitch.io/v1/refunds/refunds--list post /refunds/list Lists all the refunds associated with the merchant, or for a specific payment if payment_id is provided # Refunds - Retrieve Source: https://api-reference.hyperswitch.io/v1/refunds/refunds--retrieve get /refunds/{refund_id} Retrieves a Refund. This may be used to get the status of a previously initiated refund # Refunds - Update Source: https://api-reference.hyperswitch.io/v1/refunds/refunds--update post /refunds/{refund_id} Updates the properties of a Refund object. This API can be used to attach a reason for the refund or metadata fields # Customers - Create Source: https://api-reference.hyperswitch.io/v2/customers/customers--create-v1 post /v1/customers Creates a customer object and stores the customer details to be reused for future payments. Incase the customer already exists in the system, this API will respond with the customer details. # Customers - Delete Source: https://api-reference.hyperswitch.io/v2/customers/customers--delete-v1 delete /v1/customers/{id} Delete a customer record. # Customers - List Source: https://api-reference.hyperswitch.io/v2/customers/customers--list-v1 get /v1/customers/list Lists all the customers for a particular merchant id. # Customers - Retrieve Source: https://api-reference.hyperswitch.io/v2/customers/customers--retrieve-v1 get /v1/customers/{id} Retrieves a customer's details. # Customers - Update Source: https://api-reference.hyperswitch.io/v2/customers/customers--update-v1 put /v1/customers/{id} Updates the customer's details in a customer object. # Payment Method Session - Confirm a payment method session Source: https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--confirm-a-payment-method-session-v1 post /v1/payment-method-sessions/{id}/confirm **Confirms a payment method session object with the payment method data** # Payment Method Session - Create Source: https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--create-v1 post /v1/payment-method-sessions Create a payment method session for a customer This is used to list the saved payment methods for the customer The customer can also add a new payment method using this session # Payment Method Session - Delete a saved payment method Source: https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--delete-a-saved-payment-method-v1 delete /v1/payment-method-sessions/{id} Delete a saved payment method from the given payment method session. # Payment Method Session - List Payment Methods Source: https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--list-payment-methods-v1 get /v1/payment-method-sessions/{id}/list-payment-methods List payment methods for the given payment method session. This endpoint lists the enabled payment methods for the profile and the saved payment methods of the customer. # Payment Method Session - Retrieve Source: https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--retrieve-v1 get /v1/payment-method-sessions/{id} Retrieve the payment method session # Payment Method Session - Update a saved payment method Source: https://api-reference.hyperswitch.io/v2/payment-method-session/payment-method-session--update-a-saved-payment-method-v1 put /v1/payment-method-sessions/{id}/update-saved-payment-method Update a saved payment method from the given payment method session. # Payment Method - Create Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--create-v1 post /v1/payment-methods Creates and stores a payment method against a customer. In case of cards, this API should be used only by PCI compliant merchants. # Payment Method - Delete Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--delete-v1 delete /v1/payment-methods/{id} Deletes a payment method of a customer. # Payment Method - List Customer Saved Payment Methods Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--list-customer-saved-payment-methods-v1 get /v1/customers/{id}/saved-payment-methods List the payment methods saved for a customer # Payment Method - Get Payment Method Token Data Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--payment-method-token-to-payment-method-id-v1 get /v1/payment-methods/token/{payment_method_temporary_token}/details Retrieve the Payment method id associated with a payment method token. # Payment method retrieve v1 Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--retrieve-v1 get /v1/payment-methods/{id} # Payment Method - Set Default Payment Method for Customer Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--set-default-payment-method-for-customer-v1 post /v1/{customer_id}/payment-methods/{payment_method_id}/default Set the Payment Method as Default for the Customer. # Payment Method - Update Source: https://api-reference.hyperswitch.io/v2/payment-methods/payment-method--update-v1 put /v1/payment-methods/{id}/update-saved-payment-method Update an existing payment method of a customer. # Proxy Source: https://api-reference.hyperswitch.io/v2/proxy/proxy-v1 post /v1/proxy Create a proxy request # Error Codes Source: https://api-reference.hyperswitch.io/essentials/error_codes Hyperswitch uses error codes, types, and messages to communicate errors during API calls. There are two main types of error codes: Error Codes and Unified Error Codes. 1. **Error Codes** refer to the error code sent by the connector. 2. **Unified Error Codes** refer to the generic error code sent by the Hyperswitch server, based on the connector's error code. Hyperswitch groups the different error codes from connectors into more generic Unified Error Codes for structured relay of PSP errors, helping merchants derive patterns and determine the next steps for ongoing transactions. There are four types of Error Codes and five types of Unified Error Codes. **1. Error Codes:** The section below contains all the error codes and their corresponding error messages. | Error Code | Type | Description | | - | - | - | | IR | Invalid Request Error | Error caused due to invalid fields and values in API request | | CE | Connector Error | Errors originating from connector’s end | | HE | Hyperswitch Error | Errors originating from Hyperswitch’s end | | WE | Webhook Error | Errors related to Webhooks | | Error Codes | HTTP Status codes | Error Type | Error message | Error Handling | | - | - | - | - | - | | IR\_00 | 501 | server\_not\_available | This API is under development and will be made available soon | No action required. If you require this feature, please reach out to Hyperswitch support | | IR\_01 | 401 | invalid\_request\_error | API key not provided or invalid API key used. Provide the API key in the Authorization header using api-key (e.g api-key: API\_KEY) or create a new API key from the dashboard | Provide the API key in the Authorization header using api-key (e.g api-key: API\_KEY) or create a new API key from the dashboard | | IR\_02 | 404 | invalid\_request\_error | Unrecognized request URL | Please recheck and enter the correct request URL. Refer to our API documentation | | IR\_03 | 405 | invalid\_request\_error | The HTTP method is not applicable for this API | Please recheck the HTTP method used in the request. Refer to our API documentation | | IR\_04 | 400 | invalid\_request\_error | Missing required param: “field\_name” | Please pass the missing required parameter. Refer to our API documentation | | IR\_05 | 422 | invalid\_request\_error | “field\_name” contains invalid data. Expected format is “expected\_format” | Please pass the data in the expected format. Refer to our API documentation | | IR\_06 | 400 | invalid\_request\_error | “message” | Refer to our API documentation for required fields and format | | IR\_07 | 400 | invalid\_request\_error | Invalid value provided: “field\_name” | Provide a valid value for the required fields in the expected format. Refer to our API documentation | | IR\_08 | 400 | invalid\_request\_error | Client secret was not provided | Provide the client secret received in payments/create API response | | IR\_09 | 400 | invalid\_request\_error | The client\_secret provided does not match the client\_secret associated with the Payment | Provide the same client secret received in payments/create API response for the corresponding payment | | IR\_10 | 400 | invalid\_request\_error | Customer has an existing mandate/subscription | Cancel the active mandates/subscriptions for the customer before proceeding to delete the customer data | | IR\_11 | 400 | invalid\_request\_error | Customer has already been redacted | Customer has already been redacted. No action required | | IR\_12 | 400 | invalid\_request\_error | Reached the maximum refund attempts | Maximum refund attempts reached for this payment. Please contact Hyperswitch support for attempting more refunds for the same payment | | IR\_13 | 400 | invalid\_request\_error | Refund amount exceeds the payment amount | Please verify and pass a refund amount equal to or less than the payment amount | | IR\_14 | 400 | invalid\_request\_error | This Payment could not be “current\_flow” because it has a “field\_name” of “current\_value”. The expected state is “states” | Please verify the status of the payment and make sure that you are performing an action that is allowed for the current status of the payment | | IR\_15 | 400 | invalid\_request\_error | Invalid Ephemeral Key for the customer | Please pass the right Ephemeral key for the customer | | IR\_16 | 400 | invalid\_request\_error | “message” | Typically used when information involving multiple fields or previously provided information doesn’t satisfy a condition. Refer to our API documentation for required fields and format | | IR\_17 | 401 | invalid\_request\_error | Access forbidden, an invalid JWT token was used | Provide a valid JWT token to access the APIs | | IR\_18 | 401 | invalid\_request\_error | "message" | The user is not authorised to update the customer, Contact Org. Admin for the appropriate access. | | IR\_19 | 400 | invalid\_request\_error | "message" | Please check and retry with correct details. Refer to our API documentation | | IR\_20 | 400 | invalid\_request\_error | "flow" not supported by the "connector" | Requested flow is not supported for this Connector. | | IR\_21 | 400 | invalid\_request\_error | Missing required params | Please add the required params in the request. Refer to our API documentation | | IR\_22 | 403 | invalid\_request\_error | Access forbidden. Not authorized to access this "resource" | Contact Org. Admin for the appropriate access. | | IR\_23 | 400 | invalid\_request\_error | "message" | Use a supported file provider. Refer to our API documentation | | IR\_24 | 422 | processing\_error | Invalid "wallet\_name" wallet token | Share the correct wallet token. | | IR\_25 | 400 | invalid\_request\_error | Cannot delete the default payment method | Check if the Payment method is activated. Refer to Control centre to check this. | | IR\_26 | 400 | invalid\_request\_error | Invalid Cookie | Recheck the site setting for the cookies. | | IR\_27 | 404 | invalid\_request\_error | Extended card info does not exist | Recheck the card info shared in the request. | | IR\_28 | 400 | invalid\_request\_error | "message" | Use a valid currency. Refer to our API documentation | | IR\_29 | 422 | invalid\_request\_error | "message" | The data format is invalid for this request. Refer to our API documentation | | IR\_30 | 400 | invalid\_request\_error | Merchant connector account is configured with invalid config | Correct the config for merchant connector account | | IR\_31 | 400 | invalid\_request\_error | Card with the provided iin does not exist | Check the IIN (Issuer Identification Number) and ensure it is correct. | | IR\_32 | 400 | invalid\_request\_error | The provided card IIN length is invalid, please provide an iin with 6 or 8 digits | Provide a valid IIN with either 6 or 8 digits. | | IR\_33 | 400 | invalid\_request\_error | File not found / valid in the request | Ensure the required file is included in the request and is valid. Refer to our API documentation | | IR\_34 | 400 | invalid\_request\_error | Dispute id not found in the request | Ensure that a valid dispute ID is included in the request. | | IR\_35 | 400 | invalid\_request\_error | File purpose not found in the request or is invalid | Specify a valid file purpose in the request. | | IR\_36 | 400 | invalid\_request\_error | File content type not found / valid | Ensure the file content type is specified and is valid. | | IR\_37 | 404 | invalid\_request\_error | "message" | Check the request for the resource being accessed and ensure it exists. | | IR\_38 | 400 | invalid\_request\_error | "message" | Check for any duplicate entries in the request and correct them. | | IR\_39 | 400 | invalid\_request\_error | required payment method is not configured or configured incorrectly for all configured connectors | Verify that the required payment method is correctly configured for all connectors in use. | | CE\_00 | Status codes shared by the connectors | connector\_error | “message” | The error code and message passed from the connectors. Refer to the respective connector’s documentation for more information on the error | | CE\_01 | 400 | processing\_error | Payment failed during authorization with the connector. Retry payment | Retry the payment again as payment failed at the connector during authorization | | CE\_02 | 400 | processing\_error | Payment failed during authentication with the connector. Retry payment | Retry the payment again as payment failed at the connector during authentication | | CE\_03 | 400 | processing\_error | Capture attempt failed while processing with the connector | Capture failed for the payment at the connector. Please retry the payment | | CE\_04 | 400 | processing\_error | The card data is invalid | Invalid card data passed. Please pass valid card data | | CE\_05 | 400 | processing\_error | The card has expired | Card expired. Please pass valid card data | | CE\_06 | 400 | processing\_error | Refund failed while processing with the connector. Retry refund | Refund failed to process at the connector. Please retry refund | | CE\_07 | 400 | processing\_error | Verification failed while processing with the connector. Retry operation | Retry the operation again as verification failed at the connector | | CE\_08 | 400 | processing\_error | Dispute operation failed while processing with connector. Retry operation | Retry the operation again as dispute failed at the connector | | CE\_09 | 400 | invalid\_request\_error | Payout validation failed | Retry the operation again with correct Payout details. | | HE\_00 | 422,500 | server\_not\_available | Resource not available right now, Please try again later. | Please Wait for a few moments and try again. If the error still persists, please reach out to Hyperswitch support | | HE\_01 | 400,422 | duplicate\_request | Requested operation(Customer, Payments, Merchants, Refunds etc.) for these identifier already exists. | Please verify the Details(Customer, Payments, Merchants, Refunds, as applicable on the basis of request) and enter valid details. | | HE\_02 | 404 | object\_not\_found | Requested object(Customer, Payments, Merchants, Refunds etc.) does not exist in our records | Please verify the Details(Customer, Payments, Merchants, Refunds, as applicable on the basis of request) and enter valid details. | | HE\_03 | 500 | validation\_error | Validation Failed for the requested operation with the given details. | Please verify the details again and enter valid details | | HE\_04 | 404 | object\_not\_found | Requested object(Customer, Payments, Merchants, Refunds etc.) does not exist in our records | Please verify the Details(Customer, Payments, Merchants, Refunds, as applicable on the basis of request) and enter valid details. | | HE\_05 | 500 | processing\_error | Missing or invalid tenant details. | Please verify the tenant Details and try again. | | WE\_01 | 400 | invalid\_request\_error | Failed to authenticate the webhook | Please verify the authentication credentials and try again. | | WE\_02 | 400 | invalid\_request\_error | Bad request received in webhook | Check the request parameters and format, then try again. | | WE\_03 | 500 | router\_error | There was some issue processing the webhook | Please try again later. If the issue persists, contact Hyperswitch support. | | WE\_04 | 404 | object\_not\_found | Webhook resource not found | Ensure the webhook URL is correct and the resource exists. | | WE\_05 | 400 | invalid\_request\_error | Unable to process the webhook body | Ensure the webhook body is correctly formatted and try again. | | WE\_06 | 400 | invalid\_request\_error | Merchant Secret set by merchant for webhook source verification is invalid | Verify the Merchant Secret, then try again. | **2. Unified Error codes:** The section below contains all the unified error codes and their corresponding error messages. | Unified Error Code | Unified Error Categorisation | Unified Error message | | - | - | - | | UE\_1000 | Customer Error | Issue with payment method details. | | UE\_2000 | Connector Declines | Issue with Configurations. | | UE\_3000 | Connector Error | Technical issue with PSP. | | UE\_4000 | Integration Error | Issue in the integration. | | UE\_9000 | Others | Something went wrong. | ## Error Details Structure Hyperswitch returns a structured `error_details` object for failed payments. This object combines error information from the connector (PSP), the issuer (bank), and Hyperswitch's own interpretation. **Unified Details** This section is Hyperswitch's understanding of the failure. It is created by looking at the issuer and connector error signals and mapping them to a standard meaning. * **Category** - The high-level unified error code (for example `UE_1000` for payment method issues). * **Message** - High level unified error message that is consistent across different connectors. * **Standardised Code** - Code that identifies the specific cause for a failure within a broader error category such as `INVALID_EXPIRY_DATE`. * **Description** - A detailed description of the error intended for debugging, analytics, and support teams. * **User Guidance Message** - A user-friendly message that can be safely displayed to the customer. This message provides guidance on what the user should do to resolve the issue. * **Recommended Action** - A field that tells merchants what action to take after a payment failure. | Action | Description | | - | - | | `do_not_retry` | Never retry with same card | | `retry_later` | Retry after some time | | `retry_after_1_hour` | Retry after 1 hour | | `retry_after_24_hours` | Retry after 24 hours | | `retry_after_2_days` | Retry after 2 days | | `retry_after_4_days` | Retry after 4 days | | `retry_after_6_days` | Retry after 6 days | | `retry_after_8_days` | Retry after 8 days | | `retry_after_10_days` | Retry after 10 days | | `retry_after_instrument_update` | Retry after updating payment details | | `retry_with_different_payment_method_data` | Use different payment method | | `stop_recurring` | Stop recurring payments | ## Enhanced Errors This table provides a standardized mapping that translates granular payment error into consistent standardised codes, customer-facing messages and description. The classification mappings, user guidance message and descriptions are subject to change at any time. | Standardised Code | Unified Code(Category) | Unified Message(Message) | User Guidance Message | Description | | - | - | - | - | - | | **PAYMENT\_METHOD\_ISSUE** | **UE\_1000** | **Issue with payment method details** | **Issue with Payment Method details** | **Issue with Payment Method details** | | INVALID\_CARD\_NUMBER | UE\_1000 | Issue with payment method details | The card number doesn't look right. Please check it and try again | The card number is invalid | | INVALID\_EXPIRY\_DATE | UE\_1000 | Issue with payment method details | The card's expiry date seems incorrect or has passed. Update it or use another card. | Expiry date is in the past or improperly formatted. | | INVALID\_CVV | UE\_1000 | Issue with payment method details | The security code (CVV) is incorrect. Please re-enter it. | CVV is missing, malformed, or does not match issuer records | | PM\_ADDRESS\_MISMATCH | UE\_1000 | Issue with payment method details | The billing address doesn't match what the bank has on file. Update it or use another card. | Address mismatch (AVS failed) | | INSUFFICIENT\_FUNDS | UE\_1000 | Issue with payment method details | There aren't enough funds on this card. Use another card or add funds and try again | The entered card has insufficient funds | | CREDIT\_LIMIT\_EXCEEDED | UE\_1000 | Issue with payment method details | This card has reached its credit limit. Use another card or contact your bank. | Transaction exceeds cardholder's credit limit | | VELOCITY\_LIMIT\_EXCEEDED | UE\_1000 | Issue with payment method details | This card has hit a usage limit set by your bank. Try another card or contact your bank. | Transaction exceeds allowed frequency or velocity | | CARD\_LOST\_OR\_STOLEN | UE\_1000 | Issue with payment method details | The bank has blocked this card. Please use a different card. | This card has been reported as lost or stolen | | CARD\_NOT\_SUPPORTED\_RESTRICTED | UE\_1000 | Issue with payment method details | This card can't be used for this payment. Try another card or payment method. | Card is restricted for this merchant, channel, or use case | | ACCOUNT\_CLOSED\_OR\_INVALID | UE\_1000 | Issue with payment method details | This account is not active. Use a different payment method. | Account closed or invalid or missing | | AUTHORIZATION\_MISSING\_OR\_REVOKED | UE\_1000 | Issue with payment method details | This payment can't be completed because the prior authorization was canceled. Try another card or contact your bank. | Customer authorization is missing or was revoked | | INCORRECT\_AUTHENTICATION\_CODE | UE\_1000 | Issue with payment method details | The code you entered is incorrect. Request a new code and try again. | Incorrect authentication or verification code provided | | PAYMENT\_SESSION\_TIMEOUT | UE\_1000 | Issue with payment method details | Your session expired. Start the payment again. | Payment session expired before completion | | AUTHENTICATION\_FAILED | UE\_1000 | Issue with payment method details | We couldn't verify this payment with your bank. Try again or use a different payment method. | Authentication failed or was declined | | PAYMENT\_CANCELLED\_BY\_USER | UE\_1000 | Issue with payment method details | The payment was canceled. If this wasn't intended, please start a new payment. | Payment flow was canceled by user or system | | TRANSACTION\_NOT\_PERMITTED | UE\_1000 | Issue with payment method details | This payment method can't be used for this type of purchase. Try another payment method. | This type of purchase is not permitted or supported | | PM\_TOKENISATION\_ISSUE | UE\_1000 | Issue with payment method details | We couldn't save or use this card securely. Try again or use a different payment method. | Failed to tokenize or validate card credentials | | **CONFIGURATION\_ISSUE** | **UE\_2000** | **Issue with configuration** | **Something went wrong. Try another Payment Method** | **Issue with Configurations** | | MERCHANT\_INACTIVE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Merchant configuration inactive or invalid | | CFG\_PM\_NOT\_ENABLED\_OR\_MISCONFIGURED | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Payment method not enabled for this merchant | | CURRENCY\_OR\_CORRIDOR\_NOT\_ENABLED | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Currency or corridor not enabled | | WALLET\_OR\_TOKEN\_CONFIG\_ISSUE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Wallet or token configuration missing or incorrect | | STORED\_CREDENTIAL\_OR\_MIT\_NOT\_ENABLED | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Stored credential or MIT not enabled | | THREEDS\_CONFIGURATION\_ISSUE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | 3DS not enabled or improperly integrated. | | SUBSCRIPTION\_PLAN\_INACTIVE | UE\_2000 | Issue with configuration | Something went wrong. Try another Payment Method | Attempted charge on inactive or expired subscription | | **DOWNSTREAM\_TECHNICAL\_ISSUE** | **UE\_3000** | **Technical Issue with PSP** | **Something went wrong. Try again or contact your bank** | **Downstream technical issue** | | ISSUER\_UNAVAILABLE | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | The card issuer's bank is temporarily unavailable | | TRANSACTION\_TIMEDOUT | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Issuer timeout | | DO\_NOT\_HONOR | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Do not honor | | SUSPECTED\_FRAUD | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Issuer flagged as suspected fraud. | | PSP\_FRAUD\_ENGINE\_DECLINE | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Declined by PSP fraud engine | | COMPLIANCE\_OR\_SANCTIONS\_RESTRICTION | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Sanctions or compliance blockage | | PSP\_ACQUIRER\_ERROR | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Temporary acquirer internal error | | THREEDS\_AUTHENTICATION\_SERVICE\_ISSUE | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | 3DS Authentication Service Failure | | AUTHENTICATION\_REQUIRED | UE\_3000 | Technical Issue with PSP | Something went wrong. Try again or contact your bank | Authentication is required | | **INTEGRATION\_ISSUE** | **UE\_4000** | **Issue with integration** | **Something went wrong. Try another payment method or contact your bank** | **Issue with Integration** | | MISSING\_OR\_INVALID\_PARAM | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Missing or invalid parameter | | INVALID\_CREDENTIALS | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Invalid credentials | | OPERATION\_NOT\_ALLOWED | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Operation not allowed | | DUPLICATE\_REQUEST | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Duplicate or Idempotent request | | INVALID\_STATE | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Invalid state of operation | | THREEDS\_DATA\_OR\_PROTOCOL\_INVALID | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | 3DS payload invalid or inconsistent | | RATE\_LIMIT | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | API rate limit exceeded | | INTEG\_CRYPTOGRAPHIC\_ISSUE | UE\_4000 | Issue with integration | Something went wrong. Try another payment method or contact your bank | Token or cryptographic integration issue | | **GEN\_UNKNOWN\_ERROR** | **UE\_9000** | **Something went wrong** | **Something went wrong** | **Something went wrong** | # Go-live Checklist Source: https://api-reference.hyperswitch.io/essentials/go-live Refer to this checklist for a seamless transition as you prepare to go live with your integration. The connector configurations set up in the sandbox need to be replicated on the Hyperswitch production account. ### Signing of Hyperswitch services agreement * [ ] Ensure that the Hyperswitch services agreement is signed and shared with the Hyperswitch team. In case you need any help, please drop an email to [biz@hyperswitch.io](mailto:biz@hyperswitch.io). The Hyperswitch team will share your production Hyperswitch credentials once the above process is completed. ### Connector Configurations * [ ] Configure all the required connectors using production credentials on the Hyperswitch production dashboard and enable the required payment methods. * [ ] Ensure that the payment methods are enabled on the connector (payment processor) dashboard. * [ ] Enable raw card processing for each connector. Some connectors offer this as a dashboard toggle feature. Some processors might need you to share a PCI Attestation of Compliance over email to enable this. Drop an email to [biz@hyperswitch.io](mailto:biz@hyperswitch.io) if you need any support with PCI AOC. ### Secure your api-keys * [ ] Make sure your secret key (api-key) is not exposed on the front-end (website/mobile app). * [ ] Ensure that your workflow avoids the duplication or storage of your API keys in multiple locations. ### Set up Webhooks * [ ] [Configure your webhook endpoint](https://juspay-78.mintlify.app/essentials/webhooks#configuring-webhooks) on our dashboard to receive notifications for different events. * [ ] Update Hyperswitch's webhook endpoints on your connector's Dashboard. [Refer here](https://juspay-78.mintlify.app/essentials/webhooks#configuring-webhooks) for detailed instructions. * [ ] Update the connector secret key in our dashboard for us to authenticate webhooks sent by your connector. ### Secure your Payments * [ ] Make sure you decrypt and verify the signed payload sent along with the payment status in your return URL. * [ ] Always verify the payment amount and payment status before fulfilling your customer's shopping cart/service request. ### Error Handling * [ ] Make sure your API integration is set up to handle all the possible error scenarios (refer this [link](https://juspay-78.mintlify.app/essentials/error_codes)). * [ ] Ensure your Unified Checkout (SDK) integration is set up to handle all the possible error scenarios (refer this [link](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/errorCodes)). * [ ] Ensure that your integration can handle the entire payments lifecycle and test various scenarios using actual payment details. ### Customize and sanity check the payment experience * [ ] Ensure the pay button is properly highlighted to the customer. * [ ] Ensure a blended look and feel of the payment experience using the [styling APIs](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/customization) of Unified Checkout. # Rate Limits Source: https://api-reference.hyperswitch.io/essentials/rate_limit The Hyperswitch API has multiple checks in place to enhance its stability when faced with sudden surges of incoming traffic. Merchants who send numerous requests in rapid succession could encounter error responses indicated by the status code 429. The default rate limit for all Hyperswitch APIs is **80 requests per second**. Reach out to [biz@hyperswitch.io](mailto:biz@hyperswitch.io) if you have a requirement for higher limits. ## How to handle rate limits Effectively handling rate limit 429 errors is crucial for maintaining a seamless user experience. * Implement retry mechanisms with progressively increasing intervals to avoid overwhelming the system with repeated requests. * To proactively manage these errors, monitoring tools can help track usage patterns and provide insights for adjusting rate limits as necessary. * Ultimately, a well-orchestrated strategy for managing 429 errors not only prevents disruption but also fosters positive user engagement by transparently addressing limitations and promoting responsible API usage. ## Understanding API locking If you see a 429 error with the following error message, it is due to API locking and not due to rate limiting: ```text theme={null} At this moment, access to this object is restricted due to ongoing utilization by another API request or an ongoing Hyperswitch process. Retry after some time if this error persists. ``` API locking is a robust feature that empowers us to proactively secure and optimize access to our APIs. Our API locks objects on some operations to prevent the disruption caused by concurrent workloads that could potentially lead to inconsistent outcomes. This proactive measure not only ensures the continued integrity and performance of our APIs but also guarantees a high standard of security for our users. Once triggered, the API lock initiates a controlled pause in access, preventing any potential threats from compromising the system. # 👋 Welcome to Hyperswitch API Reference Source: https://api-reference.hyperswitch.io/introduction Hyperswitch provides a collection of APIs that enable you to process and manage payments. Our APIs accept and return JSON in the HTTP body and return standard HTTP response codes. You can consume the APIs directly using your favorite HTTP/REST library. Create your first payment using Hyperswitch APIs. Discover how to process one-time and recurring payments, save payment methods, and more. Save customer payment methods securely for future transactions Host Hyperswitch on-premise? Utilize our full API suite. ## Environment We have a testing environment referred to "sandbox," which you can set up to test API calls without affecting production data. You can sign up on our Dashboard to get API keys to access Hyperswitch API. Use the following base URLs when making requests to the APIs: | Environment | Base URL | | - | - | | Sandbox | [https://sandbox.hyperswitch.io](https://sandbox.hyperswitch.io) | | Production | [https://api.hyperswitch.io](https://api.hyperswitch.io) | If you **do not hold a PCI certification** to collect and store card data on your servers, we recommend using [**Unified Checkout**](https://hyperswitch.io/docs/sdkIntegrations/unifiedCheckoutWeb/#unified-checkout) to accept card information from users. ## Authentication and API keys Hyperswitch authenticates your API requests using your account’s API keys. Each account has two API keys for authentication: | Key | Example | When to Use | | - | - | - | | Secret key (API-key) | `snd_c69***` | Used to authenticate API requests from your merchant server. **Don’t expose this key** on a website or embed it in a mobile application. | | Publishable key | `pk_snd_3b3***` | Used to authenticate API requests from your app’s client. Can be publicly-accessible in your web or mobile app’s client-side code. | Get your [API key](https://app.hyperswitch.io/developers?tabIndex=1) and [Publishable Key](https://app.hyperswitch.io/home) [Postman Collection](https://www.postman.com/hyperswitch/workspace/hyperswitch-development/collection/25176162-630b5353-7002-44d1-8ba1-ead6c230f2e3) ## Payment Status Lifecycle Hyperswitch handles the complex functionality of a comprehensive payments flow through the Payments object that transitions through multiple states during its payments lifecycle. Given below are the various statuses a payment can have: | Payment Status | Description | | - | - | | requires\_payment\_method | Once you create a payment through payments/create endpoint with no payment method attached to it, the payments object transitions to ‘requires\_payment\_method’. | | requires\_confirmation | After attaching a payment method through payments/update endpoint, the payments object requires you to confirm the payment. | | requires\_customer\_action | Once the payment is confirmed through payments/confirm endpoint, if additional authentication is required, the payments object transitions to this state. | | requires\_capture | If you want to do separate authorize and capture, setting capture field to ‘manual’ during payments/create or confirm call will transition the payment object to this state after customer action succeeds. | | processing | In case of automatic capture, the payments object transitions to processing state post confirm call and subsequent customer authentication if available. | | succeeded | The payments object reaches success state post confirmation of successful processing from the payment processor. | | failed | The payments object transitions to a failed state when the payment processor confirms the processing failure. | ## Payment Lifecycle - more payment states | Payment Status | Description | | - | - | | Merchant Action Required | The payment is waiting on some action from the merchant (e.g., manual fraud approval) | | Partially Captured | The payment has been captured partially, and the remaining amount cannot be captured | | Partially Captured and Capturable | The payment has been captured partially and the remaining amount is capturable | | Partially Authorized and Requires Capture | The payment has been authorized for a partial amount and requires capture | | Conflicted | There has been a discrepancy between the amount/currency sent in the request and the amount/currency received by the processor. Applicable for Crypto payments and Bank transfer payments (EU) where user can change the amount on Bank page | | Expired | The payment expired before it could be captured | ## Redirect URL This is what a url looks like after redirection `https://app.hyperswitch.io?status=succeeded&payment_intent_client_secret=pay_NCv9vc19f8aa75OpFxH8_secret_V4zAc7V0C8WAw6FECMKM&amount=10000&manual_retry_allowed=false&signature=4fae0cfa775e4551db9356563d4b98b55662fe3c1c945fe215d90ccf3541282c535909ae901d82174d6b1e46ba1684aa0aa4c8861be0e2a9ef6f950a975d5014&signature_algorithm=HMAC-SHA512` The available parameters are as follows: * **status** - can have values of `succeeded`, `processing`and `failed`. * **payment\_intent\_client\_secret** - This is the client secret associated with the payment. This can be used to retrieve the payment status from hyperswitch. * **manual\_retry\_allowed** - whether this payment can be retried or not. * **signature** - A HMAC signature of the payload, this can be verified using the `payment_response_hash_key`. * **signature\_algorithm** - The HMAC algorithm used to calculate the signature. # API Key - Create Source: https://api-reference.hyperswitch.io/v1/api-key/api-key--create post /api_keys/{merchant_id} Create a new API Key for accessing our APIs from your servers. The plaintext API Key will be displayed only once on creation, so ensure you store it securely. # API Key - List Source: https://api-reference.hyperswitch.io/v1/api-key/api-key--list get /api_keys/{merchant_id}/list List all the API Keys associated to a merchant account. # API Key - Retrieve Source: https://api-reference.hyperswitch.io/v1/api-key/api-key--retrieve get /api_keys/{merchant_id}/{key_id} Retrieve information about the specified API Key. # API Key - Revoke Source: https://api-reference.hyperswitch.io/v1/api-key/api-key--revoke delete /api_keys/{merchant_id}/{key_id} Revoke the specified API Key. Once revoked, the API Key can no longer be used for authenticating with our APIs. # API Key - Update Source: https://api-reference.hyperswitch.io/v1/api-key/api-key--update post /api_keys/{merchant_id}/{key_id} Update information for the specified API Key. # Blocklist batch list Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--batch-list get /blocklist/batch # Blocklist batch status Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--batch-status get /blocklist/batch/{job_id} # Blocklist batch upload Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--batch-upload post /blocklist/batch # Blocklist - Clone Entries Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--clone post /blocklist/clone Copies a business profile's blocklist entries onto other profiles of the same merchant. The copy runs as one background job whose process tracker clones onto the targets one at a time. Poll `/blocklist/batch/{job_id}` for per-target progress in the job metadata. # Blocklist count Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--count get /blocklist/count # Blocklist export create Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--export-create post /blocklist/export # Blocklist lookup Source: https://api-reference.hyperswitch.io/v1/blocklist/blocklist--lookup get /blocklist/lookup # Delete blocklist Source: https://api-reference.hyperswitch.io/v1/blocklist/delete-blocklist delete /blocklist # Get blocklist Source: https://api-reference.hyperswitch.io/v1/blocklist/get-blocklist get /blocklist # Post blocklist Source: https://api-reference.hyperswitch.io/v1/blocklist/post-blocklist post /blocklist # Post blocklisttoggle Source: https://api-reference.hyperswitch.io/v1/blocklist/post-blocklisttoggle post /blocklist/toggle # Profile - Delete Source: https://api-reference.hyperswitch.io/v1/business-profile/business-profile--delete delete /account/{account_id}/business_profile/{profile_id} Delete the *profile* # Profile - List Source: https://api-reference.hyperswitch.io/v1/business-profile/business-profile--list get /account/{account_id}/business_profile Lists all the *profiles* under a merchant # Profile - Retrieve Source: https://api-reference.hyperswitch.io/v1/business-profile/business-profile--retrieve get /account/{account_id}/business_profile/{profile_id} Retrieve existing *profile* # Events - Delivery Attempt List Source: https://api-reference.hyperswitch.io/v1/event/events--delivery-attempt-list get /events/{merchant_id}/{event_id}/attempts List all delivery attempts for the specified Event. # Events - List Source: https://api-reference.hyperswitch.io/v1/event/events--list post /events/{merchant_id} List all Events associated with a Merchant Account or Profile. # Events - Manual Retry Source: https://api-reference.hyperswitch.io/v1/event/events--manual-retry post /events/{merchant_id}/{event_id}/retry Manually retry the delivery of the specified Event. # Gsm - Create Source: https://api-reference.hyperswitch.io/v1/gsm/gsm--create post /gsm Creates a GSM (Global Status Mapping) Rule. A GSM rule is used to map a connector's error message/error code combination during a particular payments flow/sub-flow to Hyperswitch's unified status/error code/error message combination. It is also used to decide the next action in the flow - retry/requeue/do_default # Gsm - Delete Source: https://api-reference.hyperswitch.io/v1/gsm/gsm--delete post /gsm/delete Deletes a Gsm Rule # Gsm - Get Source: https://api-reference.hyperswitch.io/v1/gsm/gsm--get post /gsm/get Retrieves a Gsm Rule # Gsm - Update Source: https://api-reference.hyperswitch.io/v1/gsm/gsm--update post /gsm/update Updates a Gsm Rule # Merchant Connector - Create Source: https://api-reference.hyperswitch.io/v1/merchant-connector-account/merchant-connector--create post /account/{account_id}/connectors Creates a new Merchant Connector for the merchant account. The connector could be a payment processor/facilitator/acquirer or a provider of specialized services like Fraud/Accounting etc. # Merchant Connector - Delete Source: https://api-reference.hyperswitch.io/v1/merchant-connector-account/merchant-connector--delete delete /account/{account_id}/connectors/{merchant_connector_id} Delete or Detach a Merchant Connector from Merchant Account # Merchant Connector - List Source: https://api-reference.hyperswitch.io/v1/merchant-connector-account/merchant-connector--list get /account/{account_id}/connectors List Merchant Connector Details for the merchant # Merchant Connector - Retrieve Source: https://api-reference.hyperswitch.io/v1/merchant-connector-account/merchant-connector--retrieve get /account/{account_id}/connectors/{merchant_connector_id} Retrieves details of a Connector account # Merchant Connector - Update Source: https://api-reference.hyperswitch.io/v1/merchant-connector-account/merchant-connector--update post /account/{account_id}/connectors/{merchant_connector_id} To update an existing Merchant Connector account. Helpful in enabling/disabling different payment methods and other settings for the connector # Platform - Create Source: https://api-reference.hyperswitch.io/v1/platform/platform--create post /user/create_platform Create a new platform account # Poll - Retrieve Poll Status Source: https://api-reference.hyperswitch.io/v1/poll/poll--retrieve-poll-status get /poll/status/{poll_id} # Relay - Create Source: https://api-reference.hyperswitch.io/v1/relay/relay post /relay Creates a relay request. # Relay - Retrieve Source: https://api-reference.hyperswitch.io/v1/relay/relay--retrieve get /relay/{relay_id} Retrieves a relay details. # Routing - Activate config Source: https://api-reference.hyperswitch.io/v1/routing/routing--activate-config post /routing/{routing_algorithm_id}/activate Activate a routing config # Routing - Create Source: https://api-reference.hyperswitch.io/v1/routing/routing--create post /routing Create a routing config # Routing - Deactivate Source: https://api-reference.hyperswitch.io/v1/routing/routing--deactivate post /routing/deactivate Deactivates a routing config # Routing - Elimination Source: https://api-reference.hyperswitch.io/v1/routing/routing--elimination post /account/{account_id}/business_profile/{profile_id}/dynamic_routing/elimination/create Create a elimination based dynamic routing algorithm # Routing - Evaluate Source: https://api-reference.hyperswitch.io/v1/routing/routing--evaluate post /routing/evaluate Evaluate routing rules # Routing - Feedback Source: https://api-reference.hyperswitch.io/v1/routing/routing--feedback post /routing/feedback Update gateway scores for dynamic routing # Routing - List Source: https://api-reference.hyperswitch.io/v1/routing/routing--list get /routing List all routing configs # Routing - Retrieve Source: https://api-reference.hyperswitch.io/v1/routing/routing--retrieve get /routing/{routing_algorithm_id} Retrieve a routing algorithm # Routing - Retrieve Config Source: https://api-reference.hyperswitch.io/v1/routing/routing--retrieve-config get /routing/active Retrieve active config # Routing - Retrieve Default Config Source: https://api-reference.hyperswitch.io/v1/routing/routing--retrieve-default-config get /routing/default Retrieve default fallback config # Routing - Retrieve Default For Profile Source: https://api-reference.hyperswitch.io/v1/routing/routing--retrieve-default-for-profile get /routing/default/profile Retrieve default config for profiles # Routing - Rule Evaluate Source: https://api-reference.hyperswitch.io/v1/routing/routing--rule-evaluate post /routing/rule/evaluate Evaluate routing rules # Routing - Auth Rate Based Source: https://api-reference.hyperswitch.io/v1/routing/routing--success-based post /account/{account_id}/business_profile/{profile_id}/dynamic_routing/success_based/create Create a success based dynamic routing algorithm # Routing - Update Default Config Source: https://api-reference.hyperswitch.io/v1/routing/routing--update-default-config post /routing/default Update default fallback config # Routing - Update Default For Profile Source: https://api-reference.hyperswitch.io/v1/routing/routing--update-default-for-profile post /routing/default/profile/{profile_id} Update default config for profiles # Outgoing webhook Source: https://api-reference.hyperswitch.io/v1/schemas/outgoing--webhook # Subscription - Cancel Subscription Source: https://api-reference.hyperswitch.io/v1/subscriptions/cancel post /subscriptions/{subscription_id}/cancel Cancel the subscription # Subscription - Confirm Source: https://api-reference.hyperswitch.io/v1/subscriptions/confirm post /subscriptions/{subscription_id}/confirm Confirms a previously created subscription. # Subscription - Create Source: https://api-reference.hyperswitch.io/v1/subscriptions/create post /subscriptions/create Creates a subscription that requires separate confirmation. # Subscription - Create and Confirm Source: https://api-reference.hyperswitch.io/v1/subscriptions/create-and-confirm post /subscriptions Creates and confirms a subscription in a single request. # Subscription - Get Estimate Source: https://api-reference.hyperswitch.io/v1/subscriptions/estimate get /subscriptions/estimate Gets pricing estimate for a subscription. # Subscription - Retrieve Source: https://api-reference.hyperswitch.io/v1/subscriptions/get get /subscriptions/{subscription_id} Retrieves subscription details by ID. # Subscription - Pause Subscription Source: https://api-reference.hyperswitch.io/v1/subscriptions/pause post /subscriptions/{subscription_id}/pause Pause the subscription # Subscription - Resume Subscription Source: https://api-reference.hyperswitch.io/v1/subscriptions/resume post /subscriptions/{subscription_id}/resume Resume the subscription # Subscription - Update Source: https://api-reference.hyperswitch.io/v1/subscriptions/update put /subscriptions/{subscription_id}/update Updates an existing subscription. # Analytics Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/analytics Routing metrics, score snapshots, and operational summaries ## What It Shows Analytics is the operator-facing view for understanding how routing is behaving in practice. The page is split into these sections: * Overview * Gateway Scoring * Decisions * Routing Stats * Logs / Summaries For single-payment inspection, use the separate Payment Audit surface documented in [`payment-audit`](/decision-engine-api-reference/payment-audit). ## Data Sources The current implementation uses these sources: * Redis for live SR and latency snapshots * Prometheus for live counters and error-rate tiles * ClickHouse as the analytics event store and analytics query backend ## Scope Analytics is always merchant-scoped by the authenticated identity: * Bearer JWT requests derive the merchant from the token claims * API-key requests derive the merchant from the key binding There is no all-merchants analytics mode. The analytics routes no longer accept `scope` or `merchant_id` query params, and changing the merchant selector in the top bar does not widen the backend query scope. Connector success-rate history is sourced from stored `score_snapshot` analytics events, not directly from Redis. Redis remains the live source for current score state. The connector SR chart can be narrowed by: * `payment_method_type` * `payment_method` * connector ## Generating Demo Traffic To populate Analytics and Decision Audit with real traffic, use the routing traffic generator. Generate traffic for `merchant_space`: ```bash theme={null} bash scripts/generate-routing-traffic.sh ``` What the script does: * creates or reuses `merchant_space` * enables success-rate routing for that merchant through the real `/rule/create` or `/rule/update` flow * sends `100` real `POST /decide-gateway` requests with mixed payment-method combinations * follows each decision with `POST /update-gateway-score` using a mix of successful and failed outcomes * creates and activates a priority-based routing rule through `/routing/create` and `/routing/activate` * sends rule-based `POST /routing/evaluate` traffic so the rule-evaluation analytics path is populated Useful overrides: ```bash theme={null} MERCHANT_ID=merchant_space TOTAL_PAYMENTS=100 bash scripts/generate-routing-traffic.sh RULE_EVALUATIONS=40 bash scripts/generate-routing-traffic.sh CONNECTORS_CSV=stripe,adyen,checkout,paypal bash scripts/generate-routing-traffic.sh ``` After the script finishes, sign in as `merchant_space` and open `/dashboard/analytics` or `/dashboard/audit`. Analytics reads will resolve the merchant from your authenticated session. ## ClickHouse Setup ClickHouse is part of the standard local runtime stacks. To bring up only ClickHouse and its schema init job: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile analytics-clickhouse up -d ``` ## Related Files * `website/src/components/pages/AnalyticsPage.tsx` * `website/src/components/layout/Sidebar.tsx` * `src/routes/analytics.rs` * `src/analytics/` * `clickhouse/scripts/` * `src/metrics.rs` ## Related Docs * [Payment Audit](/decision-engine-api-reference/payment-audit) — single-payment timeline lookups. * [ClickHouse Analytics](/decision-engine-api-reference/clickhouse-analytics) — the underlying ingestion pipeline and schema. * [Dashboard](/decision-engine-api-reference/dashboard-guide) — where these views are surfaced. # Cost Savings Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsCostSavings decision_engine_openapi-specs.json GET /analytics/cost-savings ClickHouse-backed cost savings read endpoint. # Analytics Decisions Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsDecisions decision_engine_openapi-specs.json GET /analytics/decisions ClickHouse-backed decisions read endpoint. # A/B Test Experiment Results Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsExperimentResults decision_engine_openapi-specs.json GET /analytics/experiment/{experiment_id}/results ClickHouse-backed A/B test experiment results read endpoint. # A/B Test Experiment Transactions Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsExperimentTransactions decision_engine_openapi-specs.json GET /analytics/experiment/{experiment_id}/transactions ClickHouse-backed A/B test experiment transaction log read endpoint. # Analytics Gateway Scores Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsGatewayScores decision_engine_openapi-specs.json GET /analytics/gateway-scores ClickHouse-backed gateway scores read endpoint. # Analytics Log Summaries Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsLogSummaries decision_engine_openapi-specs.json GET /analytics/log-summaries ClickHouse-backed log summaries read endpoint. # Analytics Overview Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsOverview decision_engine_openapi-specs.json GET /analytics/overview ClickHouse-backed overview read endpoint. # Payment Audit Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsPaymentAudit decision_engine_openapi-specs.json GET /analytics/payment-audit ClickHouse-backed payment audit read endpoint. # Preview Trace Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsPreviewTrace decision_engine_openapi-specs.json GET /analytics/preview-trace ClickHouse-backed rule preview trace read endpoint. # Routing Events Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsRoutingEvents decision_engine_openapi-specs.json GET /analytics/routing-events ClickHouse-backed routing events read endpoint. # Analytics Routing Stats Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsRoutingStats decision_engine_openapi-specs.json GET /analytics/routing-stats ClickHouse-backed routing stats read endpoint. # Create API Key Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/createApiKey decision_engine_openapi-specs.json POST /api-key/create Create a service-to-service API key for a merchant. # List API Keys Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/listApiKeys decision_engine_openapi-specs.json GET /api-key/list/{merchant_id} List active and revoked API keys for a merchant. # List User Merchants Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/listUserMerchants decision_engine_openapi-specs.json GET /auth/merchants Return merchants available to the current user. # Login Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/login decision_engine_openapi-specs.json POST /auth/login Create a dashboard JWT session. # Logout Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/logout decision_engine_openapi-specs.json POST /auth/logout Revoke the current dashboard JWT. # Current User Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/me decision_engine_openapi-specs.json GET /auth/me Return current authenticated user and merchant context. # Onboard Merchant Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/onboardMerchant decision_engine_openapi-specs.json POST /onboarding/merchant Create and attach a merchant to the current operator user. # Revoke API Key Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/revokeApiKey decision_engine_openapi-specs.json DELETE /api-key/{key_id} Mark an API key inactive and clear its Redis cache entry. # Signup Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/signup decision_engine_openapi-specs.json POST /auth/signup Create an operator account. Password must meet dashboard password policy. # Switch Merchant Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/auth/switchMerchant decision_engine_openapi-specs.json POST /auth/switch-merchant Switch the current dashboard merchant context. # Legacy Decision Gateway Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/compatibility/legacyDecisionGateway decision_engine_openapi-specs.json POST /decision_gateway Legacy compatibility route. New integrations should use /decide-gateway. # Legacy Update Score Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/compatibility/legacyUpdateScore decision_engine_openapi-specs.json POST /update-score Legacy compatibility route. New integrations should use /update-gateway-score. # Decide Gateway Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/gateway-decision/decideGateway decision_engine_openapi-specs.json POST /decide-gateway Core routing decision API. Given a payment context and a list of eligible gateways, returns the optimal gateway to route to. # Decide Gateway ## Use case Runs the core gateway decision flow for a payment. The same endpoint supports auth-rate routing, priority-list routing, debit/network routing, and network+SR hybrid routing. ## Authentication Protected. Send either `Authorization: Bearer ` or `x-api-key: `. In sandbox, also send `x-feature: decision-engine`. For local development, start with: ```bash theme={null} export BASE_URL=http://localhost:8080 export AUTH_HEADER="Authorization: Bearer " # Sandbox only: # export BASE_URL=https://sandbox.hyperswitch.io # export FEATURE_HEADER="x-feature: decision-engine" ``` ## Request * Method and path: `POST /decide-gateway` * Parameters: none. * Body: JSON body with `merchantId`, `paymentInfo`, `eligibleGatewayList`, and `rankingAlgorithm`. `rankingAlgorithm` must be one of `SR_BASED_ROUTING`, `PL_BASED_ROUTING`, `NTW_BASED_ROUTING`, or `NTW_SR_HYBRID_ROUTING`. ## Example ### SR based routing ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen", "checkout"], "rankingAlgorithm": "SR_BASED_ROUTING", "eliminationEnabled": true, "paymentInfo": { "paymentId": "pay_sr_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS", "cardIsin": "424242" } }' ``` ### Priority-list routing ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen", "checkout"], "rankingAlgorithm": "PL_BASED_ROUTING", "eliminationEnabled": true, "paymentInfo": { "paymentId": "pay_pl_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS", "cardIsin": "424242" } }' ``` ### Debit/network routing ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen"], "rankingAlgorithm": "NTW_BASED_ROUTING", "paymentInfo": { "paymentId": "pay_debit_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "DEBIT", "authType": "THREE_DS", "metadata": "{\"merchant_category_code\":\"merchant_category_code_0001\",\"acquirer_country\":\"US\",\"co_badged_card_data\":{\"card_type\":\"debit\",\"issuer_country\":\"US\",\"is_regulated\":false,\"regulated_name\":null,\"card_networks\":[\"VISA\",\"NYCE\",\"PULSE\",\"STAR\"]}}" } }' ``` ### Multi-objective routing ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen", "checkout"], "rankingAlgorithm": "SR_BASED_ROUTING", "eliminationEnabled": true, "enableMultiObjective": true, "paymentInfo": { "paymentId": "pay_mo_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS", "cardIsin": "424242" } }' ``` ### Network + SR hybrid routing ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen"], "rankingAlgorithm": "NTW_SR_HYBRID_ROUTING", "paymentInfo": { "paymentId": "pay_hybrid_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "DEBIT", "authType": "THREE_DS", "metadata": "{\"merchant_category_code\":\"merchant_category_code_0001\",\"acquirer_country\":\"US\",\"co_badged_card_data\":{\"card_type\":\"debit\",\"issuer_country\":\"US\",\"is_regulated\":false,\"regulated_name\":null,\"card_networks\":[\"VISA\",\"NYCE\",\"PULSE\",\"STAR\"]}}" } }' ``` ## Response ```json theme={null} { "decided_gateway": "stripe", "gateway_priority_map": { "stripe": 0.94, "adyen": 0.91 }, "routing_approach": "SR_SELECTION_V3_ROUTING", "gateway_before_evaluation": "stripe", "debit_routing_output": { "co_badged_card_networks_info": [ { "network": "NYCE", "saving_percentage": 1.2 } ], "issuer_country": "US", "is_regulated": false, "card_type": "debit" }, "is_rust_based_decider": true } ``` ## Notes * Use backend enum strings exactly; camelCase values such as `NtwBasedRouting` are invalid. * Debit routing requires the merchant debit-routing flag to be enabled and debit metadata encoded as a JSON string in `paymentInfo.metadata`. * Multi-objective routing is not a `rankingAlgorithm` value: it is a cost-aware post-step on SR-based scoring, toggled per request with `enableMultiObjective` or per merchant with the `multi_objective_routing_enabled` feature flag. When it runs, the response carries a `multi_objective_info` block, and `routing_approach` becomes `SR_SELECTION_MULTI_OBJECTIVE` when a cheaper gateway wins on expected value. * A successful call emits analytics/audit events asynchronously. ## Related * [Decide Gateway: SR Based Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-sr-based) * [Decide Gateway: PL Based Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-pl-based) * [Decide Gateway: Debit Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-debit-routing) * [Decide Gateway: Hybrid Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-hybrid-routing) * [Decide Gateway: Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) * [Update Gateway Score](/decision-engine-api-reference/api-reference/endpoint/score-feedback/updateGatewayScore) # Health Check Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/health/healthCheck decision_engine_openapi-specs.json GET /health Service liveness check. # Health Diagnostics Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/health/healthDiagnostics decision_engine_openapi-specs.json GET /health/diagnostics Database diagnostics for local and deployment troubleshooting. # Health Ready Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/health/healthReady decision_engine_openapi-specs.json GET /health/ready Returns Up when the process is ready to serve traffic. # Create Merchant Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/merchant-account/createMerchant decision_engine_openapi-specs.json POST /merchant-account/create Register a new merchant account. The merchant ID is the primary identifier used in all subsequent routing and scoring calls. # Delete Merchant Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/merchant-account/deleteMerchant decision_engine_openapi-specs.json DELETE /merchant-account/{merchant_id} Delete a merchant account and all associated routing configuration. # Get Merchant Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/merchant-account/getMerchant decision_engine_openapi-specs.json GET /merchant-account/{merchant_id} Retrieve a merchant account by ID. # Get Merchant Debit Routing Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/merchant-account/getMerchantDebitRouting decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/debit-routing Return whether debit/network routing is enabled for a merchant. Missing flag configuration is treated as disabled. # Update Merchant Debit Routing Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/merchant-account/updateMerchantDebitRouting decision_engine_openapi-specs.json POST /merchant-account/{merchant_id}/debit-routing Enable or disable runtime debit/network routing for a merchant. # Activate Routing Rule Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/activateRoutingRule decision_engine_openapi-specs.json POST /routing/activate Activate a routing rule by ID for a merchant. Only one rule can be active at a time — activating a new rule deactivates the previous one. # Create Routing Rule Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/createRoutingRule decision_engine_openapi-specs.json POST /routing/create Create a new Euclid declarative routing rule for a merchant. Supports `advanced` (full Euclid DSL), `priority` (ordered gateway list), `single` (fixed gateway), and `volume_split` (percentage-based distribution) algorithm types. # Deactivate Routing Rule Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/deactivateRoutingRule decision_engine_openapi-specs.json POST /routing/deactivate Deactivate a routing rule by ID for a merchant without deleting the saved rule. # Evaluate Routing Rule Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/evaluateRoutingRule decision_engine_openapi-specs.json POST /routing/evaluate Evaluate the active routing rule for a merchant against a payment context. Returns the ordered list of gateways selected by the rule without consuming SR data. # Get Active Routing Rule Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/getActiveRoutingRule decision_engine_openapi-specs.json POST /routing/list/active/{created_by} Retrieve the currently active routing rule for a merchant. # Hybrid Routing Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/hybridRouting decision_engine_openapi-specs.json POST /routing/hybrid Evaluate hybrid routing using the active routing rule plus runtime payment context. # List Routing Rules Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/routing-rules/listRoutingRules decision_engine_openapi-specs.json POST /routing/list/{created_by} List all routing rules for a merchant. # Create Rule Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/rule-configuration/createRuleConfig decision_engine_openapi-specs.json POST /rule/create Create a service-level configuration for `successRate` or `elimination` scoring. Controls the time window, minimum data thresholds, and other parameters used in SR computation. # Delete Rule Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/rule-configuration/deleteRuleConfig decision_engine_openapi-specs.json POST /rule/delete Delete a rule configuration. # Get Rule Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/rule-configuration/getRuleConfig decision_engine_openapi-specs.json POST /rule/get Retrieve an existing rule configuration by merchant and type. # Update Rule Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/rule-configuration/updateRuleConfig decision_engine_openapi-specs.json POST /rule/update Update an existing rule configuration. # Update Gateway Score Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/score-feedback/updateGatewayScore decision_engine_openapi-specs.json POST /update-gateway-score Feed a transaction outcome back into the success-rate model. Call this after every transaction so the engine has accurate SR data for future routing decisions. # Update Gateway Score ## Use case Records the observed transaction outcome for a previously selected gateway so auth-rate analytics can learn from real payment results. ## Authentication Protected. Send either `Authorization: Bearer ` or `x-api-key: `. In sandbox, also send `x-feature: decision-engine`. For local development, start with: ```bash theme={null} export BASE_URL=http://localhost:8080 export AUTH_HEADER="Authorization: Bearer " # Sandbox only: # export BASE_URL=https://sandbox.hyperswitch.io # export FEATURE_HEADER="x-feature: decision-engine" ``` ## Request * Method and path: `POST /update-gateway-score` * Parameters: none. * Body: JSON body with `merchantId`, `paymentId`, `gateway` and `status`, plus optional `gatewayReferenceId`, `enforceDynamicRoutingFailure`, `txnLatency`, `errorInfo` and `isSmartRetry`. ## Example ### Update gateway score ```bash theme={null} curl --location "$BASE_URL/update-gateway-score" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "paymentId": "pay_sr_001", "gateway": "stripe", "status": "CHARGED", "gatewayReferenceId": "stripe_ref_001", "enforceDynamicRoutingFailure": false, "txnLatency": { "gatewayLatency": 120.5 } }' ``` `status` must be a transaction status value - `CHARGED`, `AUTHORIZATION_FAILED`, `AUTHENTICATION_FAILED`, `JUSPAY_DECLINED`, `FAILURE`, and so on. Lowercase values such as `success` are rejected with a 400. Payment attributes (amount, currency, payment method, auth type) are **not** part of this payload - the engine already has them from the `/decide-gateway` call for this `paymentId`. Any unrecognised field is silently ignored, so a misspelled key fails quietly rather than erroring. Note in particular that latency goes in `txnLatency.gatewayLatency`, not `latency`. ## Response ```json theme={null} { "message": "Gateway score updated successfully", "merchant_id": "merchant_demo", "gateway": "stripe", "payment_id": "pay_sr_001" } ``` When `errorInfo` is supplied in the request and matches a gateway status map rule, the response also carries a `gsm_info` object describing the lookup result. ## Notes * Do not call this after `NTW_BASED_ROUTING` just to record the selected debit network; debit audit comes from `/decide-gateway` analytics. * Call it after payment authorization completes, not before. ## Related * [Decide Gateway](/decision-engine-api-reference/api-reference/endpoint/gateway-decision/decideGateway) * [Analytics Gateway Scores](/decision-engine-api-reference/api-reference/endpoint/analytics/analyticsGatewayScores) * [Update Gateway Score](/decision-engine-api-reference/api-reference/guides/feedback-scoring/update-gateway-score) # API Guide Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/api-ref A practical, copy-paste guide to the Decision Engine API — from creating a merchant to running routed transactions and reading analytics. # Decision Engine API Guide This guide walks the Decision Engine API in the order you'll actually use it: set up a merchant, configure how transactions should be routed, send transactions to `/decide-gateway`, feed outcomes back, and review analytics. Every page below includes ready-to-run `curl` examples with realistic payloads. For exact request and response schemas plus an interactive playground, use the [OpenAPI Reference](/decision-engine-api-reference/api-reference). **Two reference surfaces are available.** Start here for task-oriented flows; switch to the OpenAPI Reference when you need exact schemas. | Surface | Best for | | - | - | | **API Guide** (this section) | Copy-paste `curl` examples, end-to-end flows, and request variants. | | **[OpenAPI Reference](/decision-engine-api-reference/api-reference)** | One page per endpoint with full schemas and a request playground. | ## Integration flow A typical integration follows these steps. Each links to the page with the exact request. Create the merchant record that owns your routing config, API keys, and analytics. See [Create Merchant Account](/decision-engine-api-reference/api-reference/guides/merchant-accounts/merchant-account-create). Issue a server-to-server API key to authenticate the calls that follow. See [API Keys](/decision-engine-api-reference/api-reference/guides/auth-onboarding/api-keys). Decide how connectors are chosen — a fixed connector, a priority list, a volume split, or an advanced rule tree — then activate it. See [Create Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create). Call `/decide-gateway` for each payment to get the connector to use. See [Run Transactions](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-sr-based). Report the authorization outcome so scoring and analytics stay accurate. See [Update Gateway Score](/decision-engine-api-reference/api-reference/guides/feedback-scoring/update-gateway-score). Inspect gateway scores, decisions, and audit trails. See [Analytics & Audit](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints). ## Environment setup Set these once in your shell and reuse them across every example. ```bash theme={null} # Base URL — local source build or Docker Compose export BASE_URL=http://localhost:8080 # Sandbox (routed through Hyperswitch), when applicable # export BASE_URL=https://sandbox.hyperswitch.io # Protected endpoints accept either a dashboard JWT or an API key export AUTH_HEADER="Authorization: Bearer " # export AUTH_HEADER="x-api-key: DE_" # Sandbox-only routing header export FEATURE_HEADER="x-feature: decision-engine" # Required on analytics routes, /health/diagnostics, and /gateway-score/reset only. # "public" is the only tenant the shipped config files define. export TENANT_HEADER="x-tenant-id: public" ``` Public routes need no auth. Protected routes include `AUTH_HEADER`: ```bash theme={null} curl "$BASE_URL/analytics/overview?range=1d" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" \ --header "$FEATURE_HEADER" ``` ## Authentication & access | Access class | Routes | Required headers | | - | - | - | | Public health | `GET /health`, `GET /health/ready` | None | | Public health (tenant-scoped) | `GET /health/diagnostics` | `TENANT_HEADER` — no auth | | Public auth entry | `POST /auth/signup`, `POST /auth/login` | None | | Admin bootstrap | `POST /merchant-account/create` | Admin secret configured for the deployment | | Protected APIs | API keys, merchant reads/deletes, routing, rule config, decisions, score updates, config | `Authorization: Bearer ` or `x-api-key: ` | | Protected APIs (tenant-scoped) | All `GET /analytics/*`, `POST /gateway-score/reset` | The above, **plus** `TENANT_HEADER` | | Sandbox (Hyperswitch) | Same rules, served through `https://sandbox.hyperswitch.io` | Add `x-feature: decision-engine` | `TENANT_HEADER` (`x-tenant-id`) has no fallback — omitting it on a route that needs it fails with `TE_03: x-tenant-id not found in headers`, regardless of a valid `AUTH_HEADER`. It's easy to miss because most routes (`/decide-gateway`, `/routing/*`, `/rule/*`, `/merchant-account/*`, `/update-gateway-score`, `/auth/*`, `/api-key/*`) resolve the tenant internally and need no such header — only the routes listed above do. ## Browse by task Liveness, readiness, and dependency diagnostics. Sign up, log in, switch merchants, and manage API keys. Create, read, delete a merchant, and manage debit routing. Single, priority, volume-split, and advanced rule trees — plus activation. Success-rate and elimination (downtime) scoring config. Choose a connector per payment via `/decide-gateway`. Report authorization outcomes to keep scoring accurate. Overview, gateway scores, decisions, routing stats, and audit. Cost-aware post-step that re-ranks gateways on expected value. Learn real per-gateway fees from settlement reports and invoices. Compare two routing strategies on live traffic with guardrails. Self-tuning SR scoring, plus every merchant-level toggle. ## Ways to route transactions `/decide-gateway` supports several strategies, selected per request with `rankingAlgorithm`. | Strategy | Request value | Guide | | - | - | - | | Success-rate (auth-rate) based | `SR_BASED_ROUTING` | [SR-based routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-sr-based) | | Priority-list based | `PL_BASED_ROUTING` | [Priority-list routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-pl-based) | | Debit / network based | `NTW_BASED_ROUTING` | [Debit routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-debit-routing) | | Network + SR hybrid | `NTW_SR_HYBRID_ROUTING` | [Hybrid routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-hybrid-routing) | **Multi-objective (cost-aware) routing** is not a `rankingAlgorithm` value. It is a post-step on success-rate scoring, toggled per request with `enableMultiObjective` or per merchant with the `multi_objective_routing_enabled` feature flag. When active, responses carry a `multi_objective_info` block. See [Multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). ## Advanced capabilities Beyond the core decide/feedback loop, Decision Engine ships several self-contained systems that build on it: | Capability | What it does | Start here | | - | - | - | | Cost data ingestion | Learns each connector's actual fee (from settlement reports and invoices) at a per-cluster level, feeding multi-objective routing's expected-value ranking. | [Connector setup](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup) → [uploads](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads) → [fees & coverage](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees) | | A/B testing | Splits traffic between a control and variant routing strategy — auth vs. cost-aware, manual vs. autopilot, or any two saved algorithms — with a guardrail and significance testing. | [Create an experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) → [read results](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-results) | | Simulation | Preview what any routing algorithm (including an A/B test arm) would decide for a given payment context, without a real transaction. | [Evaluate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-evaluate) | | Autopilot & auto-calibration | Background job that self-tunes SR hedging % and bucket size from observed traffic, with a hard-reset endpoint for simulation runs. | [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features) | ## Backward compatibility Legacy routes are kept for older integrations. New integrations should use `/decide-gateway` and `/update-gateway-score`. * [Legacy decision endpoint](/decision-engine-api-reference/api-reference/guides/legacy/decision-gateway-legacy) — the older `/decision_gateway` route. * [Legacy update score](/decision-engine-api-reference/api-reference/guides/legacy/update-score-legacy) — the older `/update-score` route. # Performance Benchmarks Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/benchmarks Throughput and latency of the /decide-gateway and /routing/evaluate endpoints under sustained load ## Overview The decision engine contributes **\~6 ms** (server-side average) to a payment routing decision at typical load. A single 2-core pod sustains **835 req/s peak** with zero errors, and throughput scales linearly with additional pods — both routing modes are stateless and share no per-request mutable state. These figures are from k6 load tests against a single containerised pod. All latency numbers in the tables below represent the server-side processing time reported in each `/decide-gateway` response — the time the pod spends on the routing decision itself, excluding network distance to and from your application. | Endpoint | Algorithm | Use case | | - | - | - | | `POST /decide-gateway` | SR\_BASED\_ROUTING | Success-rate driven gateway selection | | `POST /routing/evaluate` | RULE\_BASED\_ROUTING | Priority-rule evaluation using the active configured routing rule | *** ## Test Environment **Cluster node** | Property | Value | | - | - | | vCPU capacity | 8 | | Memory capacity | 15.41 GiB | | Architecture | linux/amd64 | | Kernel | Amazon Linux 2023 (6.12.x) | **Pod provisioning** | Resource | Request | Limit | | - | -: | -: | | CPU | 1000m | 2000m | | Memory | 256 MiB | 512 MiB | **Log level:** `INFO` *** ## Test Methodology **Tool:** [k6](https://k6.io) — 30s steady load per VU step. **Metrics** * **Round-trip (RT)** — total time measured by the load generator, including local network. * **Server-side** — processing time reported by the pod in the `/decide-gateway` response `latency` field, isolating pure compute. Not available for `/routing/evaluate`. * **HTTP overhead** — round-trip minus server-side: HTTP framing, request routing, and response serialisation outside the handler's timer. Add your production network RTT on top of this. *** ## SR\_BASED\_ROUTING — `/decide-gateway` Payload: 3 card variants rotated across VUs (VISA Debit/AED, Mastercard Credit/USD, Amex Debit/EUR), 2–3 eligible gateways each. ### Throughput and latency | VUs | Throughput | RT avg | RT p50 | RT p95 | Server avg | Server p50 | Server p95 | HTTP avg | HTTP p95 | | -: | -: | -: | -: | -: | -: | -: | -: | -: | -: | | 5 | 38 req/s | 8 ms | 7 ms | 15 ms | 5 ms | 4 ms | 10 ms | 3 ms | 6 ms | | 20 | 147 req/s | 10 ms | 8 ms | 20 ms | 6 ms | 5 ms | 14 ms | 4 ms | 9 ms | | 50 | 345 req/s | 15 ms | 12 ms | 33 ms | 10 ms | 8 ms | 23 ms | 6 ms | 13 ms | Every `/decide-gateway` response includes a `latency` field (milliseconds) reporting the pod's own processing time. Use this in your monitoring to separate compute time from HTTP stack overhead in production. **Key observations** * Server-side p95 holds at **14 ms up to 147 req/s** (20 VUs) — gateway outages and payment-flow config are served from in-process caches, eliminating per-request DB queries. * At 50 VUs (345 req/s), server p95 is **23 ms**. * The HTTP overhead column (round-trip − server-side) reflects HTTP framing and serialisation cost, not network distance. Add your production RTT on top of the round-trip figures. These figures model realistic client behaviour with a 100 ms pause between requests. They reflect sustainable throughput for a typical integration, not raw server capacity. See the saturation section below for the throughput ceiling. ### Feedback path — `/update-gateway-score` Every `/decide-gateway` call is followed by a fire-and-forget feedback write to `/update-gateway-score`. This is what keeps SR scores current — it records the outcome of each routing decision back into Redis so the next decision reflects real gateway performance. It runs outside the routing response path and does not block the caller, but it does consume pod resources and contributes to Redis load. | VUs | Feedback avg | Feedback p95 | | -: | -: | -: | | 5 | 2 ms | 4 ms | | 20 | 3 ms | 7 ms | | 50 | 3 ms | 6 ms | Feedback latency stays flat under load because it is a single Redis write with no read dependencies. At 345 req/s (50 VUs) this means \~345 score updates per second — well within the Redis pool capacity at `pool_size = 5` with auto-pipelining. *** ### Saturation point To find the raw throughput ceiling, the same endpoint was driven with **no sleep** between requests — each VU fires as fast as the server can respond. Test conditions: release build (LTO, `codegen-units=1`), 2-CPU Docker limit, 0% error rate throughout. CPU% captured via `docker stats` in parallel; 200% = 2 cores fully utilized. | VUs | Throughput | CPU% | | -: | -: | -: | | 5 | 678 req/s | 151% | | 10 | 816 req/s | 190% | | **20** | **835 req/s** | **195%** | | 30 | 831 req/s | 198% | | 50 | 815 req/s | 198% | | 75 | 792 req/s | 196% | | 100 | 789 req/s | 198% | | 150 | 779 req/s | 197% | | 200 | 741 req/s | 197% | | 300 | 725 req/s | 199% | **Interpretation** * **Peak: 835 req/s at 20 in-flight requests.** CPU crosses 190% at 10 VUs and stays there — both cores are fully loaded from that point on. * **Sustained ceiling: 725–835 req/s** from 20 to 300 VUs with zero errors. The pod does not shed requests under overload; it queues them. * The sleep-based figures (345 req/s at 50 VUs) represent 41% of this ceiling. The gap is client think-time, not server capacity. ```bash theme={null} bash scripts/load-test/benchmark.sh --saturation --max-vus 300 --step-dur 20s ``` *** ## RULE\_BASED\_ROUTING — `/routing/evaluate` Payload: same 3 payment attribute variants (amount + authentication\_type), evaluated against an active priority rule: **checkout → stripe → adyen**. ### Throughput and latency | VUs | Throughput | RT avg | RT p50 | RT p95 | Error rate | | -: | -: | -: | -: | -: | -: | | 5 | 39 req/s | 6 ms | 4 ms | 17 ms | 0.06% | | 20 | 153 req/s | 7 ms | 4 ms | 17 ms | 0.01% | | 50 | 389 req/s | 6 ms | 4 ms | 14 ms | 0.01% | `/routing/evaluate` does not include a `latency` field in the response, so server-side and network latency cannot be separated for this endpoint. **Key observations** * p95 stays flat at **14–17 ms across all concurrency levels** and does not grow under load. * Throughput scales to **389 req/s on a single 2-core pod** — rule evaluation is pure in-memory computation with no Redis or DB I/O. *** ## SR vs Rule-based | VUs | SR throughput | SR server p95 | Rule RT p95 | | -: | -: | -: | -: | | 5 | 38 req/s | 10 ms | 17 ms | | 20 | 147 req/s | 14 ms | 17 ms | | 50 | 345 req/s | 23 ms | 14 ms | SR server-side p95 climbs at 50 VUs as Redis round-trips grow under contention. This is well below the pod's CPU saturation point (\~835 req/s peak with no-sleep load); the sleep-based test reaches Redis contention before it saturates CPU. Rule-based p95 stays flat because it issues no external I/O. *** ## Scaling Guide ### SR\_BASED\_ROUTING Ceiling per 2-core pod: **\~725–835 req/s** (835 req/s peak at 20 in-flight requests, sustained above 725 req/s all the way to 300 in-flight with zero errors). | Target throughput | Pods | CPU per pod | Notes | | -: | -: | -: | - | | \< 100 req/s | 1 | 2 cores | Comfortable headroom — well below saturation | | 100 – 400 req/s | 1 | 2 cores | Pod within capacity; latency remains flat | | 400 – 800 req/s | 1 | 2 cores | Approaching ceiling; monitor server p95 | | > 800 req/s | 2+ | 2 cores | Add pods; raise Redis `pool_size` proportionally | ### RULE\_BASED\_ROUTING | Target throughput | Pods | CPU per pod | Notes | | -: | -: | -: | - | | \< 400 req/s | 1 | 2 cores | Single pod handles comfortably | | > 400 req/s | 2+ | 2 cores | Linear scale-out; p95 remains flat | Do not set CPU requests below 1000m. The Tokio async runtime sizes its worker thread pool based on available CPUs — a very small quota results in a single worker thread and elevated latency under concurrency. *** ## What Affects Performance **Log level — largest single factor** Running at `DEBUG` emits \~55 JSON-serialised log lines per request. At 345 req/s (50 VUs) this means \~19 000 extra serialisations per second and raises server-side p95 significantly. Always set `INFO` or higher outside of active debugging. ```toml theme={null} [log.console] level = "INFO" ``` **Redis round-trips (SR routing only)** Each SR routing decision reads per-gateway SR scores from Redis, checks in-flight keys, and writes feedback scores. Gateway outage lists and per-merchant payment-flow config are served from in-process caches (30 s and 60 s TTL respectively) so only the SR score lookups reach Redis on the hot path. With `pool_size = 5` and auto-pipelining this handles the full \~835 req/s pod ceiling on a single 2-core pod. Raise `pool_size` proportionally when adding pods. ```toml theme={null} [redis] pool_size = 10 # default 5; raise when adding pods beyond the first auto_pipeline = true # keep enabled ``` **CPU allocation** The runtime sizes its worker pool based on available CPUs. With a 2-core limit the pod runs 2 concurrent async workers, which is the binding constraint for SR routing throughput. *** ## Reproducing These Results ```bash theme={null} # SR + Rule-based routing (sleep-based, realistic think-time) bash scripts/load-test/benchmark.sh # Saturation test — find raw throughput ceiling (no sleep, ramps to max VUs) bash scripts/load-test/benchmark.sh --saturation bash scripts/load-test/benchmark.sh --saturation --max-vus 300 --step-dur 20s # Results are saved to scripts/load-test/profile_results/ after each run ``` ## Related Docs * [Configuration](/decision-engine-api-reference/configuration) — log level and Redis pool settings referenced above. * [Local Setup Guide](/decision-engine-api-reference/local-setup) — bringing up the stack these benchmarks run against. * [API Guide](/decision-engine-api-reference/api-reference/guides/api-ref) — `/decide-gateway` and `/routing/evaluate` request examples. # ClickHouse Analytics Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/clickhouse-analytics ClickHouse setup notes for analytics ## Overview Decision Engine uses a Kafka to ClickHouse analytics pipeline: * API server captures full request and response bodies for API analytics events * API server publishes analytics events to Kafka * ClickHouse Kafka engine queue tables consume Kafka and materialized views fan into the raw tables ClickHouse remains the analytics read store for: * business-domain analytics events * raw API request and response events The analytics read path uses the two raw tables: * `analytics_domain_events` * `analytics_api_events` The ingestion path is explicit in ClickHouse too: * `analytics_domain_events_queue` * `analytics_api_events_queue` * `analytics_payment_audit_summary_buckets` * `analytics_domain_events_mv` * `analytics_api_events_mv` * `analytics_payment_audit_summary_buckets_mv` Payment Audit and Preview Trace now use a two-layer read shape: * raw event timelines still read from `analytics_domain_events` * summary lists read from the pre-aggregated `analytics_payment_audit_summary_buckets` The correlation key for those reads is the write-time `lookup_key`: * `payment_id` when present * otherwise `request_id` ## Local Bring-Up Start the local analytics stack: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile analytics-clickhouse up -d ``` That profile now includes ClickHouse, Kafka, and topic creation. The full runtime profiles use the same ClickHouse-native ingestion path. There is no separate Rust worker process anymore. Local Compose versions: * ClickHouse: `clickhouse/clickhouse-server:26.1` * Kafka: `apache/kafka:3.8.1` * ClickHouse database: `default` The bootstrap DDL now lives in: * `clickhouse/scripts/` ClickHouse loads those shell scripts on first boot through `/docker-entrypoint-initdb.d`. They create the raw tables, recreate the Kafka queue tables and materialized views, create the payment-audit summary bucket table, and bind the queue tables to the configured Kafka brokers and topics. The analytics data volume is persistent, so normal restarts keep historical data. If you need a clean reset: ```bash theme={null} make reset-analytics-clickhouse ``` ## Config Relevant config lives under: ```toml theme={null} [analytics] enabled = true [analytics.capture] details_max_bytes = 65536 [analytics.kafka] # container-to-container traffic uses the internal listener brokers = "kafka:19092" client_id = "decision-engine" api_topic = "api" domain_topic = "domain" acks = "all" compression = "lz4" message_timeout_ms = 5000 queue_capacity = 250 [analytics.clickhouse] url = "http://clickhouse:8123" database = "default" user = "decision_engine" password = "decision_engine" ``` There is no direct API-server write path to ClickHouse anymore. ClickHouse owns Kafka consumption through the queue tables and materialized views. ## Retention The raw analytics tables retain data for 18 months: * `analytics_api_events` * `analytics_domain_events` Custom query windows are normalized to the same 18-month lookback horizon. ## Troubleshooting Useful checks when ingestion looks stalled: ```sql theme={null} SHOW TABLES FROM default; SELECT * FROM system.kafka_consumers WHERE database = 'default'; SELECT count() FROM default.analytics_api_events; SELECT count() FROM default.analytics_domain_events; SELECT count() FROM default.analytics_payment_audit_summary_buckets; SELECT name, engine FROM system.tables WHERE database = 'default' AND name LIKE 'analytics_%'; ``` ## Related Docs * [Analytics](/decision-engine-api-reference/analytics) — the operator-facing view built on this pipeline. * [Payment Audit](/decision-engine-api-reference/payment-audit) — single-payment timeline lookups against these tables. * [Local Setup Guide](/decision-engine-api-reference/local-setup) — bringing up the `analytics-clickhouse` profile. # Configuration Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/configuration Configure Decision Engine via config files and environment variable overrides. # Configuration Guide This document explains how to configure Decision Engine for local and on-prem deployments. ## Primary Config Files * `config/development.toml`: used for host/source runs * `config/docker-configuration.toml`: used for Docker and Compose runs * `helm-charts/config/development.toml`: Kubernetes chart template config These files already exist with all required sections. Edit the one that matches your runtime rather than copying from `config.example.toml`, which is incomplete. ## Config Sections ### Server ```toml theme={null} [server] host = "0.0.0.0" port = 8080 ``` `host` is the bind address. Use `0.0.0.0` for Docker/deployed, `127.0.0.1` for local-only. ### Logging ```toml theme={null} [log.console] enabled = true level = "DEBUG" log_format = "default" ``` `log_format` accepts `"default"` (human-readable) or `"json"` (structured, recommended for prod). ### Metrics ```toml theme={null} [metrics] host = "0.0.0.0" port = 9094 ``` Prometheus metrics are exposed at `host:port/metrics`. Used by the `monitoring` Compose profile (Prometheus scrapes `9094`, Grafana at `3000`). ### Rate Limiting ```toml theme={null} [limit] request_count = 1 duration = 60 ``` Controls rate limiting on the delete APIs. `request_count` requests allowed per `duration` seconds. ### Redis cache config ```toml theme={null} [cache_config] service_config_redis_prefix = "DE_service_config_" service_config_ttl = 300 # Redis TTL for service config entries, in seconds ``` ### Database MySQL and PostgreSQL use separate config sections. **MySQL:** ```toml theme={null} [database] username = "db_user" password = "db_pass" host = "localhost" port = 3306 dbname = "decision_engine_db" ``` **PostgreSQL:** ```toml theme={null} [pg_database] pg_username = "db_user" pg_password = "db_pass" pg_host = "localhost" pg_port = 5432 pg_dbname = "decision_engine_db" ``` For Docker Compose runs both are pre-wired via service names in `config/docker-configuration.toml`. ### Multi-Tenant Schema ```toml theme={null} [tenant_secrets] public = { schema = "public" } ``` Maps tenant identifiers to database schemas. The shipped config files (`config/development.toml`, `config/docker-configuration.toml`) define only the `public` tenant — add entries for any additional tenant you want to support. Some routes resolve the tenant from an `x-tenant-id` request header rather than the authenticated merchant, and reject the request outright if it's missing (`TE_03`). Send `x-tenant-id: public` on `GET /health/diagnostics`, every `GET /analytics/*` route, and `POST /gateway-score/reset` — see [API Guide](/decision-engine-api-reference/api-reference/guides/api-ref#environment-setup). ### Redis ```toml theme={null} [redis] host = "127.0.0.1" port = 6379 ``` Redis is required — it's used for caching routing config and service config. For Docker, use the service name as host. ### Auth ```toml theme={null} [user_auth] jwt_secret = "change_me_in_production_use_32chars!!" jwt_expiry_seconds = 86400 email_verification_enabled = false ``` Use a strong, random `jwt_secret` — 32+ characters recommended. Set `email_verification_enabled = true` if you've wired an email provider. ### Admin Secret ```toml theme={null} [admin_secret] secret = "test_admin" ``` Used to authenticate the `POST /merchant-account/create` endpoint (admin bootstrap). Change this in production. ### API Key Auth ```toml theme={null} api_key_auth_enabled = true ``` Top-level flag. When `true`, protected routes accept `x-api-key` in addition to JWT bearer tokens. When `false`, the auth middleware allows **all requests through without authentication** — this effectively disables auth for every protected route. Do not set this to `false` in any environment that should enforce auth. ### Analytics Both Kafka and ClickHouse require `enabled = true` — without it, analytics is disabled even if the connection details are configured. ```toml theme={null} [analytics.kafka] enabled = true brokers = "localhost:9092" api_topic = "api" domain_topic = "domain" [analytics.clickhouse] enabled = true url = "http://localhost:8123" user = "decision_engine" password = "decision_engine" ``` Decision outcomes are published to Kafka and consumed into ClickHouse. Both are required for analytics and audit dashboard views. For Docker runs, these are pre-configured and enabled via the Compose profiles. ### TLS ```toml theme={null} [tls] certificate = "cert.pem" private_key = "key.pem" ``` Paths to PEM-format certificate and key files. Only needed if you're terminating TLS at the app layer rather than a reverse proxy. ### API Client ```toml theme={null} [api_client] client_idle_timeout = 90 pool_max_idle_per_host = 10 identity = "" ``` Controls the outbound HTTP client used for upstream calls. Set `identity` to a PEM path if you need mTLS. ## Secrets Management By default, secrets in config are stored in plaintext. For production, use one of the two supported backends. ### AWS KMS Requires the `kms-aws` feature (included in the `release` feature set). ```toml theme={null} [secrets_management] secrets_manager = "aws_kms" [secrets_management.aws_kms] key_id = "your-kms-key-id" region = "us-east-1" ``` ### HashiCorp Vault Requires the `kms-hashicorp-vault` feature. ```toml theme={null} [secrets_management] secrets_manager = "hashi_corp_vault" [secrets_management.hashi_corp_vault] url = "http://127.0.0.1:8200" token = "hvs.your_token" ``` When a secrets manager is configured, sensitive fields like `database.password` and `user_auth.jwt_secret` are resolved from the vault rather than the config file. ## Environment Overrides Selected values can be overridden at runtime via environment variables. This is useful in Helm deployments via `extraEnvVars`. Consult `src/config.rs` for the full mapping. ## Related Docs * [Installation](/decision-engine-api-reference/installation) * [Local Setup Guide](/decision-engine-api-reference/local-setup) * [API Guide](/decision-engine-api-reference/api-reference/guides/api-ref) * [API Reference](/decision-engine-api-reference/api-reference) # Dashboard Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/dashboard-guide Local dashboard routes and how they are served ## Availability The dashboard is available in the `dashboard-*` Docker Compose profiles. Example: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile dashboard-postgres-ghcr up -d ``` Then open: * `http://localhost:8081/dashboard/` The dashboard is served by Nginx from the built assets in `website/dist`. This docs page intentionally lives at `/dashboard-guide` — `/dashboard/` is reserved for the React app itself. ## What It Includes Based on the React routes in `website/src/App.tsx`, the dashboard exposes: * `/dashboard/` * `/dashboard/login` * `/dashboard/signup` * `/dashboard/onboarding` * `/dashboard/routing` * `/dashboard/routing/sr` * `/dashboard/routing/rules` * `/dashboard/routing/volume` * `/dashboard/routing/debit` * `/dashboard/decisions` * `/dashboard/analytics` * `/dashboard/audit` For source-run Vite development, the same React routes are mounted at `http://localhost:5173/`. For external production hosting, the preferred route is `/decision-engine/` with API traffic proxied through `/decision-engine-api/*`. ## Docs And API In The Same Profile The same `dashboard-*` profiles also expose: * Mintlify docs at `http://localhost:8081/introduction` * API examples at `http://localhost:8081/api-refs/api-ref` * the API at `http://localhost:8080` Proxy behavior is defined in `nginx/nginx.conf`. ## Related Files * `website/src/App.tsx` * `website/src/components/pages/*` * `docker-compose.yaml` * `nginx/nginx.conf` ## Related Docs * [Installation](/decision-engine-api-reference/installation) * [Local Setup Guide](/decision-engine-api-reference/local-setup) * [Analytics](/decision-engine-api-reference/analytics) * [Payment Audit](/decision-engine-api-reference/payment-audit) # Installation Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/installation Everything needed to get Decision Engine running locally, end to end. # Installation Guide This section covers everything needed to get Decision Engine running locally — from a single `docker compose up` to the full CLI, Docker, Compose, and Helm matrix. ## Prerequisites The Quick Start below pulls prebuilt images from GHCR, so you do **not** need Rust, `make`, or a local database. You do need: * **Docker Engine 20+** * **Docker Compose v2+** (the `docker compose` subcommand, not the legacy `docker-compose` binary) * **The repository cloned locally** — the compose command reads `docker-compose.yaml`, so run it from the repo root: ```bash theme={null} git clone https://github.com/juspay/decision-engine.git cd decision-engine ``` * Network access to pull `ghcr.io/juspay/...` images and a few GB of free disk (the first run pulls the app, PostgreSQL, Redis, Kafka, ClickHouse, and Mailpit). ## Quick Start The fastest path to a running instance. Every service in `docker-compose.yaml` is gated behind a profile, so a profile is required — there is no default/unprofiled bring-up: ```bash theme={null} docker compose --profile postgres-ghcr up -d curl http://localhost:8080/health ``` Expected response: ```json theme={null} { "message": "Health is good" } ``` For the API, dashboard, and docs together, use `--profile dashboard-postgres-ghcr` instead — see [Dashboard](/decision-engine-api-reference/dashboard-guide). ## In This Section | Page | Use it for | | - | - | | [Local Setup](/decision-engine-api-reference/local-setup) | The canonical guide — Compose profiles, source builds, Docker images without Compose, Helm, and troubleshooting. | | [PostgreSQL Setup](/decision-engine-api-reference/setup-guide-postgres) | Postgres-specific Compose profiles, `make` targets, and verification. | | [MySQL Setup](/decision-engine-api-reference/setup-guide-mysql) | The same, for MySQL. | | [Configuration](/decision-engine-api-reference/configuration) | Config file reference and environment variable overrides once the service is up. | | [Dashboard](/decision-engine-api-reference/dashboard-guide) | Bring up the React operator dashboard alongside the API. | ## Choosing A Database Decision Engine supports PostgreSQL and MySQL as interchangeable backends. Pick one and follow its dedicated guide, or go straight to [Local Setup](/decision-engine-api-reference/local-setup) if you want the full profile matrix (dashboard, monitoring, source builds) rather than a database-first walkthrough. ## Next Steps * [API Guide](/decision-engine-api-reference/api-reference/guides/api-ref) — copy-paste `curl` examples once the service is running. # Decision Engine Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/introduction What Decision Engine does — routing strategies, cost-aware routing, A/B testing, autopilot, analytics, and the dashboard ## What It Is Decision Engine is a Rust service that sits between your orchestrator and your payment gateways. On every payment, it picks the best gateway from an eligible list — by rule, by live success rate, by cost, or some mix of all three — and records the outcome so future decisions keep improving. It runs standalone over HTTP: no vendor lock-in, no mandatory orchestrator. ## Core Capabilities ### Routing Strategies `POST /decide-gateway` picks a connector using one of these strategies: | Strategy | What it does | | - | - | | **Rule-based routing** | Priority order, single fixed connector, percentage volume split, or a full AND/OR/nested condition tree — authored via Euclid, Juspay's open rule engine, and evaluated in `POST /routing/create`/`/routing/evaluate`. | | **Success-rate (auth-rate) based routing** | `SR_BASED_ROUTING` — ranks gateways by live transaction success rate, with hedging (exploration) and automatic downtime elimination for failing gateways. | | **Debit / network-based routing** | `NTW_BASED_ROUTING` — routes debit transactions by co-badged card network for cost/compliance reasons. | | **Network + SR hybrid routing** | `NTW_SR_HYBRID_ROUTING` — combines network eligibility with success-rate ranking. | | **Multi-objective (cost-aware) routing** | Not a `rankingAlgorithm` value — a post-step *on top of* success-rate routing. Re-ranks gateways with cost data by expected value and promotes a cheaper one if it wins. See below. | The first four are selected per request with `rankingAlgorithm`. See the [routing configuration guides](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) and [decide-gateway examples](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-sr-based) for full request/response detail. ### Multi-Objective (Cost-Aware) Routing A post-step on top of success-rate scoring: after SR picks a head gateway, Decision Engine re-ranks every gateway with cost data by **economic value** (`EV = auth rate × settlement value`, where `settlement value = txn amount − cost of payment processing (acquirer, issuer & network fee)`), and promotes a cheaper gateway if it wins on EV. Toggle it per request (`enableMultiObjective`) or per merchant (`multi_objective_routing_enabled` feature flag). See [Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). ### Cost Data Ingestion Learns each connector's *real* fee — not a static rate card — from settlement reports and invoices, fitted down to a per-cluster level (connector × card network × variant × funding × issuer country × currency × interchange category). This is what feeds multi-objective routing's cost side. Reports arrive by webhook, scheduled poll, or manual upload; fees can be read, overridden per connector or per cluster, and audited for coverage. See [Cost Ingestion: Connector Setup](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup). ### A/B Testing Split live traffic between a control and variant routing strategy — auth-only vs. cost-aware, manual vs. autopilot, or any two saved algorithms — with a configurable split percentage, a minimum sample size, and a guardrail that auto-flags a regression before it does damage. Built-in statistical significance testing (two-sample z-test) tells you when a variant actually wins. See [A/B Testing: Create An Experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create). ### Autopilot & Auto-Calibration A background job that self-tunes success-rate scoring — hedging percentage and bucket size — from observed traffic, with no manual retuning. Every calibration run is logged as an auditable event, and a merchant can hard-reset live scores back to a clean baseline at any time. See [Merchant Features: Autopilot & Feature Flags](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features). ### Analytics & Audit ClickHouse-backed views for everything above: routing overview, gateway score trends, decision volume, cost savings, routing events (leader changes, autopilot re-tunes), and a single-payment audit trail that answers "which gateway was picked, and why" for any transaction. See [Analytics Endpoints](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints) and [Payment Audit](/decision-engine-api-reference/payment-audit). ### Dashboard A React operator UI for configuring routing, running A/B tests, watching analytics, and auditing decisions without touching the API directly. See [Dashboard](/decision-engine-api-reference/dashboard-guide). ### Platform * **Multi-DB** — MySQL and PostgreSQL as interchangeable backends. * **Team management** — invite and manage members per merchant account, with role-based access. * **API keys** — server-to-server auth alongside dashboard JWT sessions. * **Debit routing gate** — per-merchant toggle for debit-network routing. ## Main API Surface The API is organized into the following endpoint groups: | Group | Endpoints | Purpose | | - | - | - | | Health | `GET /health`, `GET /health/ready`, `GET /health/diagnostics` | Liveness, readiness, and dependency diagnostics. | | Auth | `POST /auth/signup`, `POST /auth/login`, `GET /auth/me` | Dashboard operator sign-up, login, and session. | | Decisions | `POST /decide-gateway` | Choose a connector for a payment — see Routing Strategies above. | | Feedback | `POST /update-gateway-score` | Report authorization outcomes back to scoring. | | Merchant accounts | `POST /merchant-account/create`, `GET`/`DELETE /merchant-account/{merchantId}`, feature flags, debit-routing settings | Manage merchants and their configuration. | | Routing | `POST /routing/*`, `POST /rule/*` | Create, activate, evaluate, and A/B test routing algorithms. | | Cost ingestion | `POST/GET/DELETE /merchant-account/{merchantId}/connectors/*`, `.../cost-*` | Connector credentials, settlement/invoice uploads, fee overrides. | | Analytics | `GET /analytics/*` | Gateway scores, decisions, cost savings, routing events, experiment results, audit. | For copy-paste `curl` examples of each flow, see the [API Guide](/decision-engine-api-reference/api-reference/guides/api-ref). For exact request and response schemas, use the OpenAPI-backed endpoint pages under [API Reference](/decision-engine-api-reference/api-reference). ## Run Locally For API only: ```bash theme={null} docker compose --profile postgres-ghcr up -d curl http://localhost:8080/health ``` For API + dashboard + docs: ```bash theme={null} docker compose --profile dashboard-postgres-ghcr up -d ``` URLs: * API: `http://localhost:8080` * Dashboard: `http://localhost:8081/dashboard/` * Docs: `http://localhost:8081/introduction` Use [Installation](/decision-engine-api-reference/installation) for the full Compose, database, and Helm matrix. ## Where To Go Next * [Installation](/decision-engine-api-reference/installation) — Docker Compose, PostgreSQL/MySQL setup, and configuration, end to end. * [Dashboard](/decision-engine-api-reference/dashboard-guide) — route-by-route guide to the React operator dashboard. * [API Guide (curl examples)](/decision-engine-api-reference/api-reference/guides/api-ref) — copy-paste flows for every route family, including cost ingestion, A/B testing, and autopilot. * [API Reference (OpenAPI)](/decision-engine-api-reference/api-reference) — schema-backed endpoint pages with a request playground. # Local Setup Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/local-setup Full Docker Compose, source-build, and Helm matrix for running Decision Engine locally. # Local Setup Guide This is the canonical local startup guide for Decision Engine. ## Prerequisites * Docker 20+ * Docker Compose v2+ * Git 2+ Required for source runs: * Rust 1.85+ * PostgreSQL or MySQL * Redis * [`just`](https://just.systems) — required for PostgreSQL source runs (`just migrate-pg`); MySQL can use `diesel migration run` directly ## Runtime Tracks Decision Engine supports two local tracks: 1. **Published-image track** — pull existing images. 2. **Local-build track** — build images or binaries from the current source tree. Default tags used in this repo: * `DECISION_ENGINE_TAG=v1.4` * `GROOVY_RUNNER_TAG=v1.4` ## Docker Compose Profiles You must pass at least one profile. ### Core runtime profiles | Profile | DB | Includes | | - | - | - | | `postgres-ghcr` | PostgreSQL | API + PostgreSQL + Redis + Kafka + ClickHouse + PG migrations | | `postgres-local` | PostgreSQL | API + PostgreSQL + Redis + Kafka + ClickHouse + PG migrations | | `mysql-ghcr` | MySQL | API + MySQL + Redis + Kafka + ClickHouse + MySQL migrations + routing-config | | `mysql-local` | MySQL | API + MySQL + Redis + Kafka + ClickHouse + MySQL migrations + routing-config | ### Dashboard profiles | Profile | DB | Includes | | - | - | - | | `dashboard-postgres-ghcr` | PostgreSQL | core PG stack + dashboard + Mintlify docs | | `dashboard-postgres-local` | PostgreSQL | core PG stack + dashboard + Mintlify docs | | `dashboard-mysql-ghcr` | MySQL | core MySQL stack + dashboard + Mintlify docs | | `dashboard-mysql-local` | MySQL | core MySQL stack + dashboard + Mintlify docs | ### Optional profiles | Profile | Adds | | - | - | | `monitoring` | Prometheus + Grafana | | `groovy-ghcr` | Groovy runner image | | `groovy-local` | Groovy runner built from local source | | `analytics-clickhouse` | Kafka topic init + ClickHouse analytics bootstrap only | ## Fastest Bring-Up ### One-Command Local Dev For local source-run development with the full PostgreSQL analytics stack: ```bash theme={null} ./oneclick.sh ``` For the full end-to-end regression gate owned by the Cypress branch: ```bash theme={null} npm run test:e2e ``` That command runs: * source-run validation through `oneclick.sh` * Docker Compose validation through `dashboard-postgres-local` * the full Cypress API/UI/docs smoke contract against both modes Mode-specific entrypoints: ```bash theme={null} npm run test:e2e:source npm run test:e2e:docker ``` This flow: * starts PostgreSQL, Redis, Kafka, ClickHouse, and the analytics init jobs with Docker Compose * waits for infra health * runs PostgreSQL migrations * starts the API locally with `cargo run --no-default-features --features postgres` * starts the dashboard locally with Vite on `http://localhost:5173/` By default, `Ctrl+C` stops the local API/dashboard processes and any infra services that `oneclick.sh` started itself. To keep infra running after exit: ```bash theme={null} ONECLICK_KEEP_INFRA=1 ./oneclick.sh ``` ### API Only ```bash theme={null} docker compose --profile postgres-ghcr up -d ``` ### API + Dashboard + Docs ```bash theme={null} docker compose --profile dashboard-postgres-ghcr up -d ``` ### With Monitoring ```bash theme={null} docker compose --profile postgres-ghcr --profile monitoring up -d ``` ## Make Targets Common wrappers: ```bash theme={null} make init-pg-ghcr make init-pg-local make init-mysql-ghcr make init-mysql-local make run-pg-ghcr make run-mysql-local make reset-analytics-clickhouse make stop ``` ## Analytics Bootstrap The Kafka to ClickHouse analytics path is bootstrapped automatically. * Kafka topics are created by `kafka-init` * ClickHouse loads analytics SQL from `clickhouse/scripts/` on first boot * analytics data is stored in the named Docker volume `clickhouse-data` * normal restarts keep analytics history intact If you need a clean analytics rebuild, use: ```bash theme={null} make reset-analytics-clickhouse ``` That removes the ClickHouse analytics volume and recreates the Kafka + ClickHouse analytics stack. ## Source Build And Run ### PostgreSQL ```bash theme={null} cargo build --release --no-default-features --features middleware,kms-aws,postgres just migrate-pg RUSTFLAGS="-Awarnings" cargo run --no-default-features --features postgres ``` ### MySQL ```bash theme={null} cargo build --release --features release RUSTFLAGS="-Awarnings" cargo run --features release ``` ## Docker Builds Without Compose ```bash theme={null} docker build --platform=linux/amd64 -t decision-engine-mysql:local -f Dockerfile . docker build --platform=linux/amd64 -t decision-engine-pg:local -f Dockerfile.postgres . ``` Example container run: ```bash theme={null} docker run --platform=linux/amd64 \ -v $(pwd)/config/docker-configuration.toml:/local/config/development.toml \ -p 8080:8080 \ decision-engine-pg:local ``` ## Helm Chart location: `helm-charts/` ```bash theme={null} cd helm-charts helm dependency update helm install my-release . ``` Use `helm dependency update`, not `helm dependency build` — the committed `Chart.lock` digest can drift out of sync with `Chart.yaml`, and `build` fails hard on any mismatch (`Error: the lock file (Chart.lock) is out of sync with the dependencies file`). `update` re-resolves and re-fetches the `postgresql`, `mysql`, and `redis` subcharts from the Bitnami repo unconditionally. For image overrides, use `image.repository`, `image.version`, and `image.pullPolicy`. Verify with `helm install --dry-run` or `helm template` before applying to a cluster. ## Verification ```bash theme={null} curl http://localhost:8080/health ``` Expected response: ```json theme={null} {"message":"Health is good"} ``` Dashboard profiles also expose: * Dashboard: `http://localhost:8081/dashboard/` * Docs: `http://localhost:8081/introduction` * API examples: `http://localhost:8081/api-refs/api-ref` Monitoring profile also exposes: * Prometheus: `http://localhost:9090` * Grafana: `http://localhost:3000` ## Troubleshooting ### Recreate a profile with clean volumes ```bash theme={null} docker compose --profile postgres-ghcr down -v docker compose --profile postgres-ghcr up -d ``` ### Inspect migration jobs ```bash theme={null} docker compose logs db-migrator-postgres docker compose logs db-migrator ``` ### Inspect analytics infrastructure ```bash theme={null} docker compose logs kafka-init docker compose logs clickhouse ``` Check the ClickHouse schema directly: ```bash theme={null} curl --user decision_engine:decision_engine \ "http://localhost:8123/?query=SHOW%20TABLES%20FROM%20default" ``` ### Common Next Files To Inspect * `docker-compose.yaml` * `config/docker-configuration.toml` * `src/config.rs` * `src/app.rs` ## Related Docs * [Installation](/decision-engine-api-reference/installation) * [PostgreSQL Setup](/decision-engine-api-reference/setup-guide-postgres) * [MySQL Setup](/decision-engine-api-reference/setup-guide-mysql) * [Configuration](/decision-engine-api-reference/configuration) * [API Guide](/decision-engine-api-reference/api-reference/guides/api-ref) # Payment Audit Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/payment-audit Search a payment or request and inspect the full routing timeline ## What It Shows Payment Audit is the operator-facing timeline view for a single payment or request. Use it when you want to answer questions like: * which gateway was decided for this payment * which priority rule was hit * whether a score update succeeded or failed * what structured event payload was captured at each step The page is designed for exact lookups first and broad operator filtering second. ## Search Inputs The page supports these filters: * `payment_id` * `request_id` * `gateway` * `route` * `status` * `flow_type` * time window: `15m`, `1h`, `12h`, `1d`, `1w` Use an exact `payment_id` when you have it. If you only have a request trace, use `request_id`. Payment Audit is always merchant-scoped by the authenticated JWT or API key. The route does not accept `scope` or `merchant_id` query params. ## Timeline Stages The timeline is built from analytics events captured by the live request flows. Current stages include: * `gateway_decided` * `rule_applied` * `score_updated` * `preview_evaluated` * `request_read_failed` * `validation_failed` * `request_parse_failed` * `score_update_failed` The raw flow type remains visible as well, for example `decide_gateway_decision`, `decide_gateway_rule_hit`, `update_gateway_score_update`, or `routing_evaluate_advanced`. ## Data Sources Payment Audit reads from the same ClickHouse analytics store used by the analytics surface. The read path is split intentionally: * exact `payment_id` / `request_id` lookups read the raw `analytics_domain_events` timeline * broad search results read pre-aggregated `analytics_payment_audit_summary_buckets` Both views correlate events through the write-time `lookup_key`, which prefers `payment_id` and falls back to `request_id`. Relevant fields include: * `merchant_id` * `payment_id` * `request_id` * `event_stage` * `route` * `gateway` * `routing_approach` * `rule_name` * `status` * `error_code` * `error_message` * `details` The `details` field is shown as structured JSON when available. ## Route When the dashboard profile is running, open: * `http://localhost:8081/dashboard/audit` ## Related Files * `website/src/components/pages/PaymentAuditPage.tsx` * `src/routes/analytics.rs` * `src/analytics/models.rs` * `src/analytics/service.rs` * `src/decider/gatewaydecider/` * `src/feedback/gateway_scoring_service.rs` ## Related Docs * [Analytics](/decision-engine-api-reference/analytics) — the broader operator-facing metrics view. * [ClickHouse Analytics](/decision-engine-api-reference/clickhouse-analytics) — the underlying ingestion pipeline and schema. * [Dashboard](/decision-engine-api-reference/dashboard-guide) — where this view is surfaced. # MySQL Setup Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/setup-guide-mysql Set up Decision Engine with a MySQL database. # MySQL Setup Guide This page provides MySQL-focused commands. For the full end-to-end setup — CLI, Docker, Compose, Helm — see the [Local Setup Guide](/decision-engine-api-reference/local-setup). ## Docker Compose (GHCR track) ```bash theme={null} export DECISION_ENGINE_TAG=v1.4 COMPOSE_PROFILES= docker compose --profile mysql-ghcr up -d ``` With dashboard + docs: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile dashboard-mysql-ghcr up -d ``` ## Docker Compose (Local build track) ```bash theme={null} COMPOSE_PROFILES= docker compose --profile mysql-local up -d --build ``` With dashboard + docs: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile dashboard-mysql-local up -d --build ``` ## Make targets ```bash theme={null} make init-mysql-ghcr make init-mysql-local ``` ## Verify ```bash theme={null} curl http://localhost:8080/health ``` Expected response: ```json theme={null} {"message":"Health is good"} ``` ## Related Docs * [Installation](/decision-engine-api-reference/installation) * [Local Setup Guide](/decision-engine-api-reference/local-setup) * [PostgreSQL Setup](/decision-engine-api-reference/setup-guide-postgres) * [Configuration](/decision-engine-api-reference/configuration) # PostgreSQL Setup Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/setup-guide-postgres Set up Decision Engine with a PostgreSQL database. # PostgreSQL Setup Guide This page provides PostgreSQL-focused commands. For the full end-to-end setup — CLI, Docker, Compose, Helm — see the [Local Setup Guide](/decision-engine-api-reference/local-setup). ## Docker Compose (GHCR track) ```bash theme={null} export DECISION_ENGINE_TAG=v1.4 COMPOSE_PROFILES= docker compose --profile postgres-ghcr up -d ``` With dashboard + docs: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile dashboard-postgres-ghcr up -d ``` ## Docker Compose (Local build track) ```bash theme={null} COMPOSE_PROFILES= docker compose --profile postgres-local up -d --build ``` With dashboard + docs: ```bash theme={null} COMPOSE_PROFILES= docker compose --profile dashboard-postgres-local up -d --build ``` ## Make targets ```bash theme={null} make init-pg-ghcr make init-pg-local ``` ## Verify ```bash theme={null} curl http://localhost:8080/health ``` Expected response: ```json theme={null} {"message":"Health is good"} ``` ## Related Docs * [Installation](/decision-engine-api-reference/installation) * [Local Setup Guide](/decision-engine-api-reference/local-setup) * [MySQL Setup](/decision-engine-api-reference/setup-guide-mysql) * [Configuration](/decision-engine-api-reference/configuration) # Add Data in Locker Source: https://api-reference.hyperswitch.io/locker-api-reference/cards/add-data-in-locker rust_locker_open_api_spec post /data/add Add sensitive data in the locker # Delete Data from Locker Source: https://api-reference.hyperswitch.io/locker-api-reference/cards/delete-data-from-locker rust_locker_open_api_spec post /data/delete Delete sensitive data from the locker # Get or insert the data fingerprint Source: https://api-reference.hyperswitch.io/locker-api-reference/cards/get-or-insert-the-card-fingerprint post /data/fingerprint Get or insert the data fingerprint # Retrieve Data from Locker Source: https://api-reference.hyperswitch.io/locker-api-reference/cards/retrieve-data-from-locker rust_locker_open_api_spec post /data/retrieve Retrieve sensitive data from the locker # Provide Key 1 Source: https://api-reference.hyperswitch.io/locker-api-reference/key-custodian/provide-key-1 rust_locker_open_api_spec post /custodian/key1 Provide the first key to unlock the locker # Provide Key 2 Source: https://api-reference.hyperswitch.io/locker-api-reference/key-custodian/provide-key-2 rust_locker_open_api_spec post /custodian/key2 Provide the second key to unlock the locker # Unlock the locker Source: https://api-reference.hyperswitch.io/locker-api-reference/key-custodian/unlock-the-locker rust_locker_open_api_spec post /custodian/decrypt Unlock the locker with the key1 and key2 provided # Add Data in Locker Source: https://api-reference.hyperswitch.io/locker-api-reference/locker-general-purpose-storage/add-data-in-locker locker-v2 post /api/v2/vault/add Add sensitive data in the locker # Delete Data from Locker Source: https://api-reference.hyperswitch.io/locker-api-reference/locker-general-purpose-storage/delete-data-from-locker locker-v2 post /api/v2/vault/delete Delete sensitive data from the locker # Get or insert the data fingerprint Source: https://api-reference.hyperswitch.io/locker-api-reference/locker-general-purpose-storage/get-or-insert-the-card-fingerprint locker-v2 post /api/v2/vault/fingerprint Get or insert the data fingerprint # Retrieve Data from Locker Source: https://api-reference.hyperswitch.io/locker-api-reference/locker-general-purpose-storage/retrieve-data-from-locker locker-v2 post /api/v2/vault/retrieve Retrieve sensitive data from the locker # Get Health Source: https://api-reference.hyperswitch.io/locker-api-reference/locker-health/get-health rust_locker_open_api_spec get /health To check whether the application is up # Overview Source: https://api-reference.hyperswitch.io/locker-api-reference/overview The Hyperswitch Card Vault is a highly performant and a secure vault to save sensitive data such as payment card details, bank account details etc. It is designed in an polymorphic manner to handle and store any type of sensitive information making it highly scalable with extensive coverage of payment methods and processors. Hyperswitch Card Vault is built with a GDPR compliant personal identifiable information (PII) storage and secure encryption algorithms to be fully compliant with PCI DSS requirements. Here's a quick guide to [Get Started](https://github.com/juspay/hyperswitch-card-vault/blob/main/docs/guides/setup.md) with setting up Hyperswitch Card Vault. ## How does Hyperswitch Card Vault work? * Your application will communicate with Hyperswitch Card Vault via a middleware. * All requests and responses to and from the middleware are signed and encrypted with the JWS and JWE algorithms. * The locker supports CRD APIs on the /data and /cards endpoints - * Cards are stored against the combination of merchant and customer identifiers. * Internal hashing checks are in place to avoid data duplication. ![general-block-diagram](https://raw.githubusercontent.com/juspay/hyperswitch-card-vault/45dc1e5ca168f811b9230ede9e644ccb6f03a28c/docs/imgs/general-block-diagram.png) ## Key Hierarchy * Master Key - AES generated key to that is encrypted/decrypted by the custodian keys to run the locker and associated configurations. * Custodian Keys - AES generated key that is used to encrypt and decrypt the master key. It broken into two keys (key 1 and key 2) and available with two custodians to enhance security. ![lock-key-hierarchy](https://raw.githubusercontent.com/juspay/hyperswitch-card-vault/45dc1e5ca168f811b9230ede9e644ccb6f03a28c/docs/imgs/locker-key-hierarchy.png) ## Setup Guide Follow this guide to setup - [Get Started](https://github.com/juspay/hyperswitch-card-vault/blob/main/docs/guides/setup.md) # Configure SR Dimensions Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/compatibility/configSrDimension decision_engine_openapi-specs.json POST /config-sr-dimension Configure success-rate routing dimensions. # Get Routing Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/compatibility/getRoutingConfig decision_engine_openapi-specs.json GET /config/routing-keys Return rule-builder routing keys and supported values. # Get SR Dimensions Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/compatibility/getSrDimensions decision_engine_openapi-specs.json GET /config-sr-dimension/{merchant_id} Retrieve the success-rate routing dimension configuration for a merchant. # Delete Connector Credentials Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/deleteConnectorCredentials decision_engine_openapi-specs.json DELETE /merchant-account/{merchant_id}/connectors/{connector}/credentials/{account} Remove a connector account's stored cost-report credentials. # Delete Cost Ingestion Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/deleteCostIngestion decision_engine_openapi-specs.json DELETE /merchant-account/{merchant_id}/cost-ingestions/{ingestion_id} Delete a specific cost ingestion and its staged data. # Delete Invoice Add-on Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/deleteInvoiceAddon decision_engine_openapi-specs.json DELETE /merchant-account/{merchant_id}/connectors/{connector}/invoice-addon Remove a connector's invoice-derived fee add-on. # Get Cost Coverage Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/getCostCoverage decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/cost-coverage Summary of how much of the merchant's volume is covered by good (well-modelled) cost clusters. # Get Invoice Reconciliation Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/getInvoiceReconciliation decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/invoice-reconciliation Reconciliation of invoice subtotals against modelled + add-on captured fees, per connector. # List Connector Credentials Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/listConnectorCredentials decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/connectors Masked list of connector cost-report credentials configured for the merchant. # List Connector Fees Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/listConnectorFees decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/connector-fees Per-connector modelled and effective fee rates (model, override and effective pct_bps/fixed). # List Cost Clusters Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/listCostClusters decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/cost-clusters Learned per-dimension cost clusters (network/funding/country/currency/IC category) with modelled and effective fees. # List Cost Ingestions Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/listCostIngestions decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/cost-ingestions History of uploaded/pulled cost-report ingestions with staged rows, gross, and status. # List Cost Price Changes Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/listCostPriceChanges decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/cost-price-changes Detected changes in cluster pricing (old vs new pct_bps/fixed) across ingestions. # List Invoice Add-ons Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/listInvoiceAddons decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/invoice-addons Per-connector periodic-fee add-ons learned from uploaded invoices. # Set Cost Cluster Override Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/setClusterOverride decision_engine_openapi-specs.json PUT /merchant-account/{merchant_id}/cost-clusters/{cluster_key}/fee-override Override the modelled fee for a specific cost cluster identified by its cluster key. # Set Connector Credentials Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/setConnectorCredentials decision_engine_openapi-specs.json POST /merchant-account/{merchant_id}/connectors/{connector}/credentials Store the account and report-download credentials used to pull a connector's cost reports. # Set Connector Fee Override Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/connector-costs/setFeeOverride decision_engine_openapi-specs.json PUT /merchant-account/{merchant_id}/connectors/{connector}/fee-override Manually override the effective fee (pct_bps + fixed) for a connector. # Get Merchant Features Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/features/getMerchantFeatures decision_engine_openapi-specs.json GET /merchant-account/{merchant_id}/features List the merchant's feature-flag states (GSM scoring, explore/exploit, A/B, multi-objective, elimination). # Reset Gateway Scores Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/features/resetGatewayScores decision_engine_openapi-specs.json POST /gateway-score/reset Flush a merchant's live gateway (success-rate) scores and any manual overrides. # Update Merchant Feature Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/endpoint/features/updateMerchantFeature decision_engine_openapi-specs.json POST /merchant-account/{merchant_id}/features/{feature} Enable or disable a single feature flag for the merchant. # A/B Testing: Create An Experiment Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create Curl examples for creating and activating a routing A/B test via /routing/create. # A/B Testing: Create An Experiment A/B testing lets you compare two routing strategies — or two configurations of the same strategy — on a live split of traffic, with built-in guardrails and statistical significance checks. There is no separate create/manage API: an experiment is just another `algorithm.type` on the existing [`/routing/create`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) endpoint, alongside `single`, `priority`, `volume_split`, and `advanced`. ## Why run one Any routing change — turning on multi-objective routing, enabling autopilot, retuning hedging — is a bet that the new behaviour beats what you have today. The honest way to settle that bet is to run both on the *same* live traffic at the same time and measure the difference, rather than flip the change globally and hope the week-over-week numbers move for the right reason. That's what an experiment does: it holds one arm (**control**) on your current behaviour and sends a minority slice to the other (**variant**), so the two are compared under identical market conditions. The design has two safety properties built in: * **A guardrail.** If the variant's authorisation rate falls more than `guardrail_threshold_pp` percentage points below control, the experiment is flagged `GuardrailBreached` immediately — this is a deliberately eager point-estimate check, because no cost saving is worth an auth regression, and it trips without waiting for statistical significance (once past the minimum sample gate). * **A significance test.** A winner is only declared when the difference is statistically real. Once each arm clears `min_sample_size`, results run a two-sample z-test on per-transaction economic value (which collapses to a plain two-proportion auth-rate test when no cost dimension is involved). Until then the verdict stays `CollectingData`; a positive-but-noisy gap stays `NotSignificant` rather than prematurely crowning the variant. Only a `p < 0.05` gap yields `VariantWins` / `VariantLoses`. See [A/B Testing: Results](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-results) for reading the verdict. Because control and variant differ only in the routing behaviour you're testing, the measured delta is attributable to that change — which is exactly why you'd run an experiment before flipping a merchant-wide flag like [multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). ## algorithm.type = "ab\_test" ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "cost-vs-auth-test", "description": "A/B test: 20% variant traffic", "created_by": "merchant_demo", "algorithm_for": "payment", "metadata": {}, "algorithm": { "type": "ab_test", "data": { "control_algorithm_id": "sr_routing", "variant_algorithm_id": "sr_routing", "variant_split_pct": 20, "min_sample_size": 1000, "guardrail_threshold_pp": 3.0, "control_sr_config": { "enable_multi_objective": false, "use_autopilot": false }, "variant_sr_config": { "enable_multi_objective": true, "use_autopilot": false } } } }' ``` Response is the standard routing-algorithm create response: ```json theme={null} { "rule_id": "routing_a1b2c3d4-1111-2222-3333-444455556666", "name": "cost-vs-auth-test", "created_at": "2026-07-16 10:00:00", "modified_at": "2026-07-16 10:00:00" } ``` ## algorithm.data (ABTestData) Fields | Field | Type | Meaning | | - | - | - | | `control_algorithm_id` | string | Algorithm the control arm uses. `"sr_routing"` for success-rate scoring, or the `rule_id` of an existing `single`/`priority`/`volume_split`/`advanced` algorithm. | | `variant_algorithm_id` | string | Same, for the variant arm. | | `variant_split_pct` | integer, 1–49 | Percentage of traffic sent to the variant arm. Capped below 50 so the variant is always the minority arm. | | `min_sample_size` | integer | Transactions each arm needs before results are considered statistically meaningful. | | `guardrail_threshold_pp` | number | Auto-pause guardrail: if the variant's auth rate drops this many percentage points below control, the experiment result is marked `GuardrailBreached`. | | `control_sr_config` | object, optional | Per-arm SR override — see below. Only meaningful when the arm's algorithm is `sr_routing`. | | `variant_sr_config` | object, optional | Same, for the variant arm. | ### SR Config Override ```json theme={null} { "hedging_percent": 5.0, "elimination_threshold": 0.35, "enable_multi_objective": true, "margin": 0.2, "use_autopilot": false } ``` All fields are optional — set only the ones you want to override for that arm; anything omitted falls back to the merchant's live SR config. `enable_multi_objective` and `use_autopilot` are the same dials used by [multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) and [autopilot](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features), scoped to just this arm. ## Common Experiment Shapes The dashboard's A/B test builder resolves its strategy dropdown into these four `sr_routing` + override combinations — useful presets when constructing the payload by hand: | Arm preset | `variant_sr_config` | | - | - | | SR routing (auth based) | `{ "enable_multi_objective": false, "use_autopilot": false }` | | SR routing (auth based, autopilot) | `{ "enable_multi_objective": false, "use_autopilot": true }` | | SR routing (multi-objective, manual) | `{ "enable_multi_objective": true, "use_autopilot": false }` | | SR routing (multi-objective, autopilot) | `{ "enable_multi_objective": true, "use_autopilot": true }` | A `sr_config_tuning` experiment (compare two SR tunings rather than two strategies) uses `sr_routing` for both arms and only sets `hedging_percent`/`elimination_threshold` on the variant, leaving control on the live config. ## Activate The Experiment Creating an experiment does not make it active — activate it like any other routing algorithm: ```bash theme={null} curl --location "$BASE_URL/routing/activate" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "created_by": "merchant_demo", "routing_algorithm_id": "routing_a1b2c3d4-1111-2222-3333-444455556666" }' ``` ## How Traffic Is Split Arm assignment is deterministic per payment: `payment_id` is hashed and taken modulo 100 against `variant_split_pct`, so retries of the same payment always land in the same arm. Two integration points use this assignment: * **Real payments** — `/decide-gateway` / `/decision_gateway` route into the assigned arm. This only happens when the merchant feature `ab-test-real-payments` is enabled — see [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features). Off by default so a newly created experiment doesn't affect live traffic until you opt in. * **Simulation / Decision Explorer** — [`/routing/evaluate`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-evaluate) previews what each arm would do for a given payment context, without a real transaction. If an arm's algorithm id resolves to `sr_routing`, the payment proceeds through normal SR routing carrying that arm's `SrConfigOverride`. If it resolves to another algorithm's id, that algorithm's output is used directly and the response's `routing_approach` becomes `AB_TEST_STATIC_ALGORITHM`. ## Editing Or Removing An Experiment Only an **inactive** experiment can be edited or deleted — see [Update & Delete Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-update-delete). Deactivate first with [`/routing/deactivate`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-deactivate) if it's currently live. ## Related * [A/B Testing: Results](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-results) * [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features) — enabling `ab-test-real-payments` and autopilot. * [Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) * [Create Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) # A/B Testing: Results Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-results Curl examples for reading A/B test results, transaction logs, and enabling real-payment interception. # A/B Testing: Results Once an experiment (see [Create An Experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create)) is active and taking traffic, use these endpoints to monitor it. Both routes below live under `/analytics/` and require `$TENANT_HEADER` in addition to `$AUTH_HEADER` — see [Environment setup](/decision-engine-api-reference/api-reference/guides/api-ref#environment-setup). ## Experiment Results Runs a statistical significance test (two-sample z-test on expected value, or plain auth-rate when the experiment is auth-only) between the control and variant arms. ```bash theme={null} curl "$BASE_URL/analytics/experiment/routing_a1b2c3d4-1111-2222-3333-444455556666/results" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` Optional query parameters: `start_ms`, `end_ms`, `min_sample_size`, `guardrail_threshold_pp`, `evaluation_margin` — override the experiment's stored thresholds for an ad-hoc window or sensitivity check. ```json theme={null} { "experiment_id": "routing_a1b2c3d4-1111-2222-3333-444455556666", "merchant_id": "merchant_demo", "control": { "arm": "control", "transaction_count": 4820, "success_count": 4531, "failure_count": 289, "auth_rate": 0.94, "first_attempt_auth_rate": 0.91, "total_cost_saved": null, "avg_latency_ms": 6.2, "avg_chosen_cost_bps": 182.4, "avg_cost_saved_bps": null, "net_ev_bps": 17660.0 }, "variant": { "arm": "variant", "transaction_count": 1204, "success_count": 1101, "failure_count": 103, "auth_rate": 0.914, "first_attempt_auth_rate": 0.887, "total_cost_saved": 962.3, "avg_latency_ms": 6.5, "avg_chosen_cost_bps": 150.1, "avg_cost_saved_bps": 32.3, "net_ev_bps": 17944.0 }, "delta_pp": -2.6, "p_value": 0.031, "confidence_interval": [-4.9, -0.3], "verdict": "variant_wins", "min_sample_size": 1000, "net_delta_bps": 284.0, "evaluation_margin": 0.2 } ``` ### Verdict Values | Verdict | Meaning | | - | - | | `collecting_data` | At least one arm hasn't reached `min_sample_size` yet. | | `not_significant` | Enough data, but the difference isn't statistically significant. | | `variant_wins` | Variant significantly outperforms control on net expected value. | | `variant_loses` | Variant significantly underperforms control. | | `guardrail_breached` | Variant's auth rate dropped more than `guardrail_threshold_pp` below control — short-circuits before significance is even computed. | For an auth-only experiment (no cost data / multi-objective involved on either arm), the significance test collapses to a pure auth-rate z-test and cost-related fields (`total_cost_saved`, `avg_cost_saved_bps`, `net_ev_bps`, `net_delta_bps`) are `null`. ## Experiment Transactions Paginated per-transaction log — which arm each payment landed in and its outcome. Useful for spot-checking arm assignment or debugging a specific payment. ```bash theme={null} curl "$BASE_URL/analytics/experiment/routing_a1b2c3d4-1111-2222-3333-444455556666/transactions?page=1&page_size=20" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```json theme={null} { "experiment_id": "routing_a1b2c3d4-1111-2222-3333-444455556666", "total": 6024, "transactions": [ { "payment_id": "pay_9f21", "variant_arm": "variant", "gateway": "adyen", "status": "success", "created_at_ms": 1784271600000 } ] } ``` `page_size` is capped at 100. Optional `start_ms` narrows to a time window. ## Enabling Real-Payment Interception A newly created experiment does not affect live traffic until real-payment interception is turned on for the merchant: ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/features/ab-test-real-payments" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "enabled": true }' ``` See [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features) for the full feature-flag reference. Until this is enabled, `/routing/evaluate` still previews both arms for simulation purposes even though `/decide-gateway` traffic is unaffected. ## Related * [A/B Testing: Create An Experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) * [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features) * [Analytics Endpoints](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints) # Analytics Endpoints Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints Curl examples for ClickHouse-backed analytics, charts, payment audit, and decision trace. # Analytics Endpoints Analytics routes derive the merchant from the authenticated user/API key context and read from the analytics store. Use these endpoints for dashboard charts, payment audit, rule/volume decision inspection, and debit-routing audit. Every route on this page also requires `x-tenant-id` (`$TENANT_HEADER` — see [Environment setup](/decision-engine-api-reference/api-reference/guides/api-ref#environment-setup)) in addition to `$AUTH_HEADER`. It has no fallback: omitting it fails with `TE_03: x-tenant-id not found in headers` even with a valid API key or JWT. This is the one header group most other Decision Engine routes (`/decide-gateway`, `/routing/*`, `/merchant-account/*`, etc.) don't need. Common query parameters: | Parameter | Values | | - | - | | `range` | `15m`, `1h`, `12h`, `1d`, `1w` | | `start_ms`, `end_ms` | custom epoch-millisecond window | | `page`, `page_size` | paginated list endpoints | | `gateway`, `status`, `route`, `flow_type`, `routing_approach`, `exclude_routing_approach` | filters | | `payment_id` | exact payment lookup for audit and trace views | | `error_code` | failure filtering | ## Overview High-level dashboard summary for the selected merchant and time window. ```bash theme={null} curl "$BASE_URL/analytics/overview?range=1d" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```json theme={null} { "request_count": 42, "top_gateway": "adyen", "gateway_share": [ { "gateway": "adyen", "count": 22, "share": 52.4 } ] } ``` ## Gateway Scores Auth-rate score snapshots and connector success-rate trend. ```bash theme={null} curl "$BASE_URL/analytics/gateway-scores?range=1d&gateway=stripe,adyen" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```json theme={null} { "latest": [ { "gateway": "adyen", "score": 0.831 }, { "gateway": "stripe", "score": 0.829 } ], "series": [ { "timestamp_ms": 1777136400000, "gateway": "adyen", "score": 0.831 } ] } ``` ## Decisions Decision volume by connector and routing approach. ```bash theme={null} curl "$BASE_URL/analytics/decisions?range=1d" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```bash theme={null} curl "$BASE_URL/analytics/decisions?range=1d&exclude_routing_approach=NTW_BASED_ROUTING" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ## Routing Stats Connector share, rule hits, routing filter options, and chart data. ```bash theme={null} curl "$BASE_URL/analytics/routing-stats?range=1d&payment_method_type=CARD" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ## Log Summaries Failure aggregates and recent error samples. ```bash theme={null} curl "$BASE_URL/analytics/log-summaries?range=1d&status=failure" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ## Payment Audit Payment-level trail search. Prefer `payment_id` for exact lookup. ```bash theme={null} curl "$BASE_URL/analytics/payment-audit?range=1d&page=1&page_size=12&payment_id=pay_001" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```bash theme={null} curl "$BASE_URL/analytics/payment-audit?range=1d&gateway=stripe&status=success&page=1&page_size=10" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```json theme={null} { "summary": { "matching_payments": 1, "failures": 0, "active_gateways": ["stripe"] }, "payments": [ { "payment_id": "pay_001", "latest_status": "success", "gateways": ["stripe"] } ], "timeline": [ { "route": "decide_gateway", "event_stage": "gateway_decided", "gateway": "stripe", "status": "success" } ] } ``` ## Preview Trace Rule/volume decisions captured from `/routing/evaluate`. The transport route remains `/analytics/preview-trace` even when the UI labels these as decisions. ```bash theme={null} curl "$BASE_URL/analytics/preview-trace?range=1d&page=1&page_size=12&route=routing_evaluate" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```bash theme={null} curl "$BASE_URL/analytics/preview-trace?range=1d&payment_id=volume_decision_001" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ## Debit Routing Audit ```bash theme={null} curl "$BASE_URL/analytics/payment-audit?range=1d&routing_approach=NTW_BASED_ROUTING" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ## Cost Savings Rollup of savings attributed to [multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) — how much cheaper the chosen gateway was versus the plain SR head, trended over the window. ```bash theme={null} curl "$BASE_URL/analytics/cost-savings?range=1w¤cy=USD" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```json theme={null} { "merchant_id": "merchant_demo", "range": "1w", "currency": "USD", "available_currencies": [ { "currency": "USD", "decision_count": 4820 }, { "currency": "EUR", "decision_count": 612 } ], "trend": [ { "bucket_ms": 1784112000000, "saved_value": 128.42 } ], "totals": { "saved_value": 962.3, "cost_won_count": 341, "total_decisions": 4820 } } ``` `currency` is optional — omit it to aggregate across all currencies present in the window. ## Routing Events Historical feed of routing-relevant state changes — SR leader changes, gateways entering/exiting the multi-objective auth band, and autopilot calibration runs. Powers the dashboard's routing timeline and the simulation UI's "Autopilot Actions" panel. ```bash theme={null} curl "$BASE_URL/analytics/routing-events?range=1d&payment_method_type=CARD" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```json theme={null} { "merchant_id": "merchant_demo", "range": "1d", "generated_at_ms": 1784271600000, "events": [ { "id": "evt_a1b2c3", "event_type": "leader_changed", "merchant_id": "merchant_demo", "payment_method_type": "CARD", "payment_method": "CREDIT", "bucket_ms": 1784268000000, "gateway": "adyen", "previous_gateway": "stripe", "score": 0.91, "previous_score": 0.885, "transaction_count": 214 } ] } ``` `event_type` is one of `leader_changed`, `gateway_entered_auth_band`, `gateway_exited_auth_band`, or `calibration_applied` (an autopilot re-tune — see [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features)). Auth-band events only fire when multi-objective routing is enabled for the merchant. Additional filters: `min_transaction_count`, `min_score_delta`, `tolerance_pp` (auth-band width override), `limit`. ## A/B Test Experiment Results Statistical significance results and the per-transaction log for a routing A/B test. Full reference, including the verdict enum and guardrail behavior: [A/B Testing: Results](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-results). ```bash theme={null} curl "$BASE_URL/analytics/experiment/routing_a1b2c3d4-1111-2222-3333-444455556666/results" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ```bash theme={null} curl "$BASE_URL/analytics/experiment/routing_a1b2c3d4-1111-2222-3333-444455556666/transactions?page=1&page_size=20" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" ``` ## Notes * Use `range` for preset windows and `start_ms`/`end_ms` for custom windows. * Use `page` and `page_size` on list-heavy views such as payment audit and preview trace. * Use `exclude_routing_approach=NTW_BASED_ROUTING` when auth-rate audit should hide debit-routing decisions. * Freshly inserted analytics events may take a short moment to appear because writes are asynchronous. # API Keys Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/auth-onboarding/api-keys Curl examples for creating, listing, and revoking Decision Engine API keys. # API Keys API keys are intended for service-to-service traffic. Use the returned `api_key` value as `x-api-key` for protected endpoints. ## Create API Key ```bash theme={null} curl --location "$BASE_URL/api-key/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "description": "backend integration key" }' ``` ```json theme={null} { "key_id": "018f...", "api_key": "DE_...", "key_prefix": "DE_abcd", "merchant_id": "merchant_demo", "description": "backend integration key", "created_at": "2026-04-25 10:00:00" } ``` ## List API Keys ```bash theme={null} curl "$BASE_URL/api-key/list/merchant_demo" \ --header "$AUTH_HEADER" ``` ## Revoke API Key ```bash theme={null} curl --request DELETE "$BASE_URL/api-key/018f-key-id" \ --header "$AUTH_HEADER" ``` # Auth And Onboarding Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/auth-onboarding/auth-and-onboarding Curl examples for dashboard auth, merchant selection, and merchant onboarding. # Auth And Onboarding ## Sign Up ```bash theme={null} curl --location "$BASE_URL/auth/signup" \ --header "Content-Type: application/json" \ --data '{ "email": "operator@example.com", "password": "StrongPass#123", "merchant_id": "merchant_demo" }' ``` ## Login ```bash theme={null} curl --location "$BASE_URL/auth/login" \ --header "Content-Type: application/json" \ --data '{ "email": "operator@example.com", "password": "StrongPass#123" }' ``` Response contains a dashboard JWT: ```json theme={null} { "token": "eyJ...", "user_id": "user_123", "email": "operator@example.com", "merchant_id": "merchant_demo", "role": "admin", "merchants": [] } ``` ## Current User ```bash theme={null} curl "$BASE_URL/auth/me" \ --header "$AUTH_HEADER" ``` ## List User Merchants ```bash theme={null} curl "$BASE_URL/auth/merchants" \ --header "$AUTH_HEADER" ``` ## Switch Merchant ```bash theme={null} curl --location "$BASE_URL/auth/switch-merchant" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo" }' ``` ## Create Merchant From Dashboard ```bash theme={null} curl --location "$BASE_URL/onboarding/merchant" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_name": "Demo Merchant" }' ``` ## Logout ```bash theme={null} curl --location "$BASE_URL/auth/logout" \ --header "$AUTH_HEADER" \ --request POST ``` ## Verify Email Public route — the link sent by the signup email-verification flow calls this with the token from the email. ```bash theme={null} curl "$BASE_URL/auth/verify-email?token=vf_9f21a6c0..." ``` ```json theme={null} { "message": "Email verified successfully." } ``` ## Change Password ```bash theme={null} curl --location "$BASE_URL/auth/change-password" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "current_password": "StrongPass#123", "new_password": "EvenStrongerPass#456" }' ``` ```json theme={null} { "message": "Password updated successfully." } ``` ## Team Management Invite and manage members on the authenticated merchant account. Inviting requires the caller's JWT to carry the `admin` role. ### List Members ```bash theme={null} curl "$BASE_URL/merchant/members" \ --header "$AUTH_HEADER" ``` ```json theme={null} [ { "user_id": "user_123", "email": "operator@example.com", "role": "admin" }, { "user_id": "user_456", "email": "teammate@example.com", "role": "member" } ] ``` ### Invite A Member ```bash theme={null} curl --location "$BASE_URL/merchant/members/invite" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "email": "teammate@example.com", "role": "member" }' ``` `role` is optional and defaults to `"member"`; the only other accepted value is `"admin"`. ```json theme={null} { "email": "teammate@example.com", "is_new_user": true, "password": "TempPass#8821", "role": "member" } ``` `password` is only present when the invite creates a brand-new user account — share it out of band so they can log in and change it. Inviting an email that's already a user omits `password` and just adds the membership. # Merchant Features: Autopilot & Feature Flags Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features Curl examples for reading and toggling merchant-level feature flags — including Autopilot and SR Auto-Calibration — and resetting gateway scores. # Merchant Features: Autopilot & Feature Flags Every merchant-level toggle — multi-objective routing, A/B test real-payment interception, elimination, and the two self-tuning features (Autopilot and SR Auto-Calibration) — is read and set through one small feature-flag API. ## List Feature Flags ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/features" \ --header "$AUTH_HEADER" ``` ```json theme={null} { "merchant_id": "merchant_demo", "features": [ { "feature": "gsm-scoring-filter", "enabled": false }, { "feature": "explore-exploit-srv3", "enabled": false }, { "feature": "ab-test-real-payments", "enabled": true }, { "feature": "multi-objective-routing", "enabled": true }, { "feature": "elimination", "enabled": true }, { "feature": "auto-calibration", "enabled": true }, { "feature": "autopilot", "enabled": true } ] } ``` ## Toggle A Feature ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/features/autopilot" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "enabled": true }' ``` Response is the same shape as the list call, re-read after the change so you always see the current effective state of every flag. ## Known Features | Slug | What it controls | | - | - | | `gsm-scoring-filter` | Filters gateway scoring using Gateway Status Mapper error-code classification. | | `explore-exploit-srv3` | Explore/exploit hedging on the SRv3 scoring path. | | `ab-test-real-payments` | Whether active A/B test experiments intercept real `/decide-gateway` traffic — see [A/B Testing: Results](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-results). | | `multi-objective-routing` | Merchant-wide default for the cost-aware post-step — see [Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). Per-request `enableMultiObjective` overrides this. | | `elimination` | Gateway-level SR-based elimination (excluding gateways in downtime). | | `auto-calibration` | Enables the self-tuning background job (see below). Must be on **together with** `autopilot` for the job to actually write changes. | | `autopilot` | Master write-permission switch for the self-tuning job. With `auto-calibration` off, this alone does nothing. | ## What Autopilot & Auto-Calibration Do The success-rate scorer has two knobs — **bucket size** (how many recent transactions each gateway's score is averaged over) and **hedging %** (how much traffic is explored away from the current leader). The right values depend on how much traffic a merchant sees and how many gateways it spreads across, and the ideal settings drift as that traffic changes through the day. Tuning them by hand is tedious and quickly goes stale. **Autopilot is the self-tuning layer that sets those two knobs for you, continuously, from observed traffic.** Instead of a fixed configuration, it watches each merchant's real volume and gateway spread and re-derives the bucket size and hedging % that keep scoring both responsive (fast to notice a gateway degrading) and stable (not thrashing on noise). "Auto-Calibration" is the background job that does the deriving; "Autopilot" is the switch that lets it actually write its results back. The two are split so you can enrol a merchant for observation without granting write access until you're ready. These two flags jointly control a background job — there is no separate "run autopilot" endpoint. `auto-calibration` gates whether the job considers a merchant at all; `autopilot` gates whether it's allowed to write. Both must be enabled for self-tuning to take effect. Every polling interval (default 900s, configurable via `[sr_auto_calibration]` in `config/*.toml` or `SR_AUTO_CALIBRATION_INTERVAL_SECS`), the job: 1. Reads recent traffic volume from ClickHouse (default 3600s lookback). 2. Derives two SRv3 knobs purely from observed data — no merchant input: * **Bucket size** — clamped between 100 and 2000, only rewritten on a meaningful (25-step) change. * **Hedging %** — capped at 30%, with a 1.0pp minimum move before it updates. 3. Writes the result back into the merchant's SR config (readable via [`GET /config/routing-keys`](/decision-engine-api-reference/api-reference/guides/scoring-config/config-endpoints) and [`GET /config-sr-dimension/:merchant_id`](/decision-engine-api-reference/api-reference/guides/scoring-config/config-endpoints#get-sr-dimensions)), stamped with `"source": "autopilot"` so autopilot-written values are distinguishable from human-authored overrides. Every calibration run also emits an analytics event (`flow_type: autopilot_calibration`) — this is what powers the "Autopilot Actions" panel in the simulation UI, and is queryable via [Routing Events](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints#routing-events). ## Reset Gateway Scores Flushes all SR v2/v3 score and queue keys for a merchant from Redis, and strips any autopilot-written (`source: "autopilot"`) sub-level config overrides — human-authored overrides are preserved. Used by the simulator's "Hard refresh" so a new simulation run starts from a clean slate. Unlike the feature-flag calls above, this route requires `$TENANT_HEADER` in addition to `$AUTH_HEADER` — see [Environment setup](/decision-engine-api-reference/api-reference/guides/api-ref#environment-setup). ```bash theme={null} curl --location "$BASE_URL/gateway-score/reset" \ --header "$AUTH_HEADER" \ --header "$TENANT_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo" }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "deleted_keys": 214, "removed_overrides": 3 } ``` This does not disable routing or delete configuration — it only clears live scoring state so the next decisions start from a fresh baseline. ## Related * [A/B Testing: Create An Experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) * [Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) * [Routing Config Endpoints](/decision-engine-api-reference/api-reference/guides/scoring-config/config-endpoints) * [Analytics Endpoints](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints) # Advanced Routing Example Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-advanced-example Advanced Euclid rule tree examples for /routing/create, including AND, OR, nested rules, and value variants. # Advanced Routing Example Use `algorithm.type = advanced` when a merchant needs conditional rule-based routing instead of a fixed connector order. Advanced rules evaluate payment attributes, choose the first matching rule output, and fall back to `default_selection` when no rule matches. ## Advanced Program Shape ```json theme={null} { "globals": {}, "default_selection": { "priority": [ { "gateway_name": "stripe", "gateway_id": "mca_stripe" } ] }, "rules": [], "metadata": {} } ``` | Field | Meaning | | - | - | | `globals` | Optional reusable value sets referenced by `global_ref`. | | `default_selection` | Fallback `single`, `priority`, `volume_split`, or `volume_split_priority` output. | | `rules[].routing_type` | Rule output behavior: `priority`, `volume_split`, or `volume_split_priority`. | | `rules[].output` | Connector output returned when the rule matches. | | `rules[].statements[].condition` | Conditions inside one statement. All conditions in the same array must match. | | `rules[].statements[].nested` | Optional nested statements. Parent condition must match and then nested statements are evaluated. | ## Full Create Request ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "advanced card routing", "created_by": "merchant_demo", "description": "Route Visa card traffic by priority, otherwise fallback to stripe", "algorithm_for": "payment", "algorithm": { "type": "advanced", "data": { "globals": {}, "default_selection": { "priority": [ { "gateway_name": "stripe", "gateway_id": "mca_stripe" } ] }, "rules": [ { "name": "visa_card_rule", "routing_type": "priority", "output": { "priority": [ { "gateway_name": "adyen", "gateway_id": "mca_adyen" }, { "gateway_name": "stripe", "gateway_id": "mca_stripe" } ] }, "statements": [ { "condition": [ { "lhs": "payment_method_type", "comparison": "equal", "value": { "type": "enum_variant", "value": "CARD" }, "metadata": {} }, { "lhs": "card_network", "comparison": "equal", "value": { "type": "enum_variant", "value": "Visa" }, "metadata": {} } ], "nested": null } ] } ], "metadata": {} } } }' ``` ## Logic Variants ### AND Rule Use one `condition` array when all conditions must match. ```json theme={null} { "name": "high_value_netherlands_rule", "routing_type": "volume_split", "output": { "volume_split": [ { "split": 60, "output": { "gateway_name": "hdfc", "gateway_id": "mca_hdfc" } }, { "split": 40, "output": { "gateway_name": "instamojo", "gateway_id": "mca_instamojo" } } ] }, "statements": [ { "condition": [ { "lhs": "amount", "comparison": "greater_than", "value": { "type": "number", "value": 100 }, "metadata": {} }, { "lhs": "billing_country", "comparison": "equal", "value": { "type": "enum_variant", "value": "Netherlands" }, "metadata": {} } ], "nested": null } ] } ``` ### OR Rule Use multiple statements when any statement can trigger the rule. ```json theme={null} { "name": "card_or_high_value_rule", "routing_type": "priority", "output": { "priority": [ { "gateway_name": "paytm", "gateway_id": "mca_paytm" }, { "gateway_name": "adyen", "gateway_id": "mca_adyen" } ] }, "statements": [ { "condition": [ { "lhs": "payment_method_type", "comparison": "equal", "value": { "type": "enum_variant", "value": "CARD" }, "metadata": {} } ], "nested": null }, { "condition": [ { "lhs": "amount", "comparison": "greater_than", "value": { "type": "number", "value": 100 }, "metadata": {} } ], "nested": null } ] } ``` ### Nested AND + OR Rule Use `nested` when a parent condition must match and then one nested branch can match. ```json theme={null} { "name": "amount_and_card_network_or_country_rule", "routing_type": "priority", "output": { "priority": [ { "gateway_name": "rbl", "gateway_id": "mca_rbl" }, { "gateway_name": "instamojo", "gateway_id": "mca_instamojo" } ] }, "statements": [ { "condition": [ { "lhs": "amount", "comparison": "greater_than", "value": { "type": "number", "value": 10 }, "metadata": {} } ], "nested": [ { "condition": [ { "lhs": "card_network", "comparison": "equal", "value": { "type": "enum_variant", "value": "Visa" }, "metadata": {} } ], "nested": null }, { "condition": [ { "lhs": "billing_country", "comparison": "equal", "value": { "type": "enum_variant", "value": "India" }, "metadata": {} } ], "nested": null } ] } ] } ``` ## Output Variants ### Priority Output ```json theme={null} { "routing_type": "priority", "output": { "priority": [ { "gateway_name": "adyen", "gateway_id": "mca_adyen" }, { "gateway_name": "stripe", "gateway_id": "mca_stripe" } ] } } ``` ### Volume Split Output ```json theme={null} { "routing_type": "volume_split", "output": { "volume_split": [ { "split": 70, "output": { "gateway_name": "stripe", "gateway_id": "mca_stripe" } }, { "split": 30, "output": { "gateway_name": "adyen", "gateway_id": "mca_adyen" } } ] } } ``` ### Volume Split Priority Output Use `volume_split_priority` when each split should return a priority list rather than a single connector. ```json theme={null} { "routing_type": "volume_split_priority", "output": { "volume_split_priority": [ { "split": 60, "output": [ { "gateway_name": "stripe", "gateway_id": "mca_stripe" }, { "gateway_name": "adyen", "gateway_id": "mca_adyen" } ] }, { "split": 40, "output": [ { "gateway_name": "checkout", "gateway_id": "mca_checkout" }, { "gateway_name": "stripe", "gateway_id": "mca_stripe" } ] } ] } } ``` ## Value Variants ### Enum Variant Array ```json theme={null} { "lhs": "card_network", "comparison": "equal", "value": { "type": "enum_variant_array", "value": ["Visa", "Mastercard"] }, "metadata": {} } ``` ### Number Array ```json theme={null} { "lhs": "amount", "comparison": "equal", "value": { "type": "number_array", "value": [1000, 2000, 5000] }, "metadata": {} } ``` ### Number Comparison Array ```json theme={null} { "lhs": "amount", "comparison": "equal", "value": { "type": "number_comparison_array", "value": [ { "comparison_type": "greater_than", "number": 1000 }, { "comparison_type": "less_than_equal", "number": 5000 } ] }, "metadata": {} } ``` ## Notes * Advanced algorithms require `statements`; top-level `single`, `priority`, and `volume_split` algorithms do not. * Conditions in the same `condition` array behave like AND. * Multiple statements behave like OR. * `nested` allows a parent condition plus nested branch matching. * `volume_split` percentages should add up to 100. ## Related * [Create Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) * [Evaluate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-evaluate) * [Priority Routing](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-priority-example) * [Volume Split Routing](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-volume-split-example) # Activate Routing Algorithm Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-activate Curl example for activating a routing algorithm. # Activate Routing Algorithm At a given time, one algorithm for each `algorithm_for` value can be active for one merchant. ## Request ```bash theme={null} curl --location "$BASE_URL/routing/activate" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "created_by": "merchant_demo", "routing_algorithm_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0" }' ``` ## Response Success returns HTTP `200` with an empty response body. ## Related * [Deactivate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-deactivate) * [List Active Routing Algorithms](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-list-active) # Create Routing Algorithm Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create Curl examples for /routing/create. # Create Routing Algorithm Use `/routing/create` to persist a merchant-scoped routing algorithm. Creating an algorithm does not make it active; call [`/routing/activate`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-activate) after creation. Supported `algorithm.type` values: | Type | Use case | Full example | | - | - | - | | `single` | Always return one connector. | [Single connector](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-single-connector-example) | | `priority` | Return connectors in the configured order. | [Priority routing](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-priority-example) | | `volume_split` | Split decisions by percentage. | [Volume split](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-volume-split-example) | | `advanced` | Evaluate AND/OR/nested conditions before returning an output. | [Advanced routing](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-advanced-example) | | `ab_test` | Split traffic between a control and variant strategy with guardrails and significance testing. | [A/B testing](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) | Use [`/routing/deactivate`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-deactivate) to deactivate the currently active algorithm without deleting it, and [update or delete](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-update-delete) an inactive algorithm in place. ## Priority Rule ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "priority rule", "created_by": "merchant_demo", "description": "try stripe before adyen", "algorithm_for": "payment", "algorithm": { "type": "priority", "data": [ { "gateway_name": "stripe", "gateway_id": "mca_111" }, { "gateway_name": "adyen", "gateway_id": "mca_112" } ] } }' ``` ## Single Connector Rule ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "single connector rule", "created_by": "merchant_demo", "description": "always route to stripe", "algorithm_for": "payment", "algorithm": { "type": "single", "data": { "gateway_name": "stripe", "gateway_id": "mca_111" } } }' ``` ## Volume Split Rule ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "volume split rule", "created_by": "merchant_demo", "description": "split traffic between stripe and adyen", "algorithm_for": "payment", "algorithm": { "type": "volume_split", "data": [ { "split": 70, "output": { "gateway_name": "stripe", "gateway_id": "mca_111" } }, { "split": 30, "output": { "gateway_name": "adyen", "gateway_id": "mca_112" } } ] } }' ``` ## Advanced Rule Use `advanced` for conditional routing. The complete AND/OR/nested reference is in [Advanced Routing Example](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-advanced-example). ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "advanced card rule", "created_by": "merchant_demo", "description": "route Visa cards to adyen first", "algorithm_for": "payment", "algorithm": { "type": "advanced", "data": { "globals": {}, "default_selection": { "priority": [{ "gateway_name": "stripe", "gateway_id": "mca_111" }] }, "rules": [ { "name": "visa_card_rule", "routing_type": "priority", "output": { "priority": [ { "gateway_name": "adyen", "gateway_id": "mca_112" }, { "gateway_name": "stripe", "gateway_id": "mca_111" } ] }, "statements": [ { "condition": [ { "lhs": "card_network", "comparison": "equal", "value": { "type": "enum_variant", "value": "Visa" }, "metadata": {} } ], "nested": null } ] } ], "metadata": {} } } }' ``` ## Response ```json theme={null} { "rule_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0", "name": "priority rule", "created_at": "2026-04-25 11:45:03", "modified_at": "2026-04-25 11:45:03" } ``` ## Related * [Activate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-activate) * [Update & Delete Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-update-delete) * [List Routing Algorithms](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-list) * [Evaluate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-evaluate) * [Advanced Routing Example](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-advanced-example) * [A/B Testing: Create An Experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) # Deactivate Routing Algorithm Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-deactivate Curl example for deactivating a routing algorithm. # Deactivate Routing Algorithm Use `/routing/deactivate` to remove the active mapping for a merchant-scoped routing algorithm without deleting the algorithm itself. ## Request ```bash theme={null} curl --location "$BASE_URL/routing/deactivate" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "created_by": "merchant_demo", "routing_algorithm_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0" }' ``` ## Response Success returns HTTP `200` with an empty response body. ## Behavior * If the routing algorithm exists and is active for the merchant, the active mapping is deleted. * If the routing algorithm exists but is already inactive, the request still succeeds. * If the routing algorithm ID does not exist, the request fails with `400`. ## Related * [Create Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) * [Activate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-activate) * [List Active Routing Algorithms](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-list-active) # Evaluate Routing Algorithm Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-evaluate Curl example for /routing/evaluate. # Evaluate Routing Algorithm `/routing/evaluate` evaluates the active routing algorithm for a payment context. It does not update SR scores. ## Request ```bash theme={null} curl --location "$BASE_URL/routing/evaluate" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "paymentInfo": { "paymentId": "eval_001", "amount": 1000, "currency": "USD", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS" } }' ``` ## Response ```json theme={null} { "priority": [ { "gateway_name": "stripe", "gateway_id": "mca_111" }, { "gateway_name": "adyen", "gateway_id": "mca_112" } ] } ``` # List Routing Algorithms Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-list Curl example for listing routing algorithms. # List Routing Algorithms ## Request ```bash theme={null} curl --request POST "$BASE_URL/routing/list/merchant_demo" \ --header "$AUTH_HEADER" ``` ## Response ```json theme={null} [ { "rule_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0", "name": "priority rule", "algorithm_for": "payment" } ] ``` # List Active Routing Algorithms Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-list-active Curl example for listing active routing algorithms. # List Active Routing Algorithms ## Request ```bash theme={null} curl --location --request POST "$BASE_URL/routing/list/active/merchant_demo" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" ``` ## Response ```json theme={null} [ { "rule_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0", "name": "priority rule", "algorithm_for": "payment" } ] ``` # Update & Delete Routing Algorithm Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-update-delete Curl examples for /routing/update and /routing/delete. # Update & Delete Routing Algorithm Edit or remove a previously created routing algorithm — including [A/B test experiments](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create), which are stored the same way. Both operations only work on an **inactive** algorithm; deactivate it first with [`/routing/deactivate`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-deactivate) if it's currently live. ## Update Rewrites the name, description, and algorithm definition in place — the `rule_id` doesn't change. ```bash theme={null} curl --location "$BASE_URL/routing/update" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "created_by": "merchant_demo", "routing_algorithm_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0", "name": "priority rule (v2)", "description": "try adyen before stripe", "algorithm": { "type": "priority", "data": [ { "gateway_name": "adyen", "gateway_id": "mca_112" }, { "gateway_name": "stripe", "gateway_id": "mca_111" } ] } }' ``` `algorithm` accepts the same `type` values as [`/routing/create`](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) — `single`, `priority`, `volume_split`, `advanced`, or `ab_test`. ```json theme={null} { "id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0", "name": "priority rule (v2)", "algorithm_for": "payment", "created_at": "2026-07-01 09:12:04", "modified_at": "2026-07-16 10:00:00" } ``` Returns an error if the algorithm is currently active, or if `created_by` doesn't own the algorithm. ## Delete ```bash theme={null} curl --location "$BASE_URL/routing/delete" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "created_by": "merchant_demo", "routing_algorithm_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0" }' ``` ```json theme={null} { "status": "deleted", "routing_algorithm_id": "routing_e641380c-6f24-4405-8454-5ae6cbceb7a0" } ``` ## Related * [Create Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-create) * [Activate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-activate) * [Deactivate Routing Algorithm](/decision-engine-api-reference/api-reference/guides/configure-routing/routing-algorithm-deactivate) * [A/B Testing: Create An Experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) # Hybrid Routing Evaluation Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-hybrid Curl example for /routing/hybrid. # Hybrid Routing Evaluation `/routing/hybrid` evaluates the active rule path together with runtime routing context. ```bash theme={null} curl --location "$BASE_URL/routing/hybrid" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "paymentInfo": { "paymentId": "hybrid_eval_001", "amount": 1000, "currency": "USD", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT" }, "eligibleGatewayList": ["stripe", "adyen"] }' ``` ```json theme={null} { "priority": [ { "gateway_name": "stripe", "gateway_id": "mca_111" }, { "gateway_name": "adyen", "gateway_id": "mca_112" } ] } ``` # Priority Routing Example Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-priority-example Priority-list routing create example. # Priority Routing Example ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "priority rule", "created_by": "merchant_demo", "algorithm_for": "payment", "algorithm": { "type": "priority", "data": [ { "gateway_name": "stripe", "gateway_id": "mca_111" }, { "gateway_name": "adyen", "gateway_id": "mca_112" }, { "gateway_name": "checkout", "gateway_id": "mca_113" } ] } }' ``` # Single Connector Example Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-single-connector-example Single-connector routing create example. # Single Connector Example ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "single connector rule", "created_by": "merchant_demo", "algorithm_for": "payment", "algorithm": { "type": "single", "data": { "gateway_name": "stripe", "gateway_id": "mca_111" } } }' ``` # Volume Split Example Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/configure-routing/routing-volume-split-example Volume-split routing create example. # Volume Split Example ```bash theme={null} curl --location "$BASE_URL/routing/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "name": "volume split rule", "created_by": "merchant_demo", "algorithm_for": "payment", "algorithm": { "type": "volume_split", "data": [ { "split": 70, "output": { "gateway_name": "stripe", "gateway_id": "mca_111" } }, { "split": 30, "output": { "gateway_name": "adyen", "gateway_id": "mca_112" } } ] } }' ``` # Cost Ingestion: Fees & Coverage Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees Curl examples for reading fitted connector fees, setting manual overrides, inspecting top cost clusters, and checking cost-model coverage. # Cost Ingestion: Fees & Coverage Once settlement data has been ingested (see [Connector Setup](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup) and [Uploads](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads)), Decision Engine fits a per-cluster cost model — the input to [multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective)'s expected-value ranking. These endpoints read that model and let you override it manually. Overrides take priority in this order: **cluster override** → **connector override** → **learned model**. ## Connector Fees Per-connector blended fee (volume-weighted over trustworthy clusters), any manual override, and which one is effective. ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/connector-fees" \ --header "$AUTH_HEADER" ``` ```json theme={null} [ { "connector": "adyen", "account": "YOUR_ADYEN_MERCHANT_ACCOUNT_CODE", "has_credentials": true, "model_pct_bps": 182.4, "model_fixed": 0.1, "good_gross": 1284302.55, "override_pct_bps": null, "override_fixed": null, "override_updated_at": null, "effective_pct_bps": 182.4, "effective_fixed": 0.1, "source": "model" } ] ``` `source` is `"override"`, `"model"`, or `"none"` (configured but no fitted data yet). ### Set A Connector Fee Override Replaces the learned model for every expected-value calculation on this connector. ```bash theme={null} curl --request PUT \ "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/fee-override" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "pct_bps": 175.0, "fixed": 0.1 }' ``` ### Delete A Connector Fee Override ```bash theme={null} curl --request DELETE \ "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/fee-override" \ --header "$AUTH_HEADER" ``` Both `pct_bps` and `fixed` must be finite and non-negative. Setting or clearing an override refreshes this merchant's served cost model immediately rather than waiting for the periodic refresh. ## Cost Clusters The highest-traffic fitted clusters (by GMV) — the fine-grained segments underneath a connector's blended fee, and the target for surgical per-cluster overrides. ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/cost-clusters?limit=10" \ --header "$AUTH_HEADER" ``` Narrow to one connector's latest snapshot, or one exact ingestion: ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/cost-clusters?connector=adyen&account=YOUR_ADYEN_MERCHANT_ACCOUNT_CODE" \ --header "$AUTH_HEADER" ``` ```json theme={null} [ { "key": "adyen|visa|credit|credit|us|usd|domestic", "connector": "adyen", "card_network": "visa", "variant": "credit", "funding": "credit", "issuer_country": "us", "currency": "usd", "ic_category": "domestic", "n": 18422, "gross_sum": 512300.2, "model_pct_bps": 178.2, "model_fixed": 0.1, "override_pct_bps": null, "override_fixed": null, "override_updated_at": null, "effective_pct_bps": 178.2, "effective_fixed": 0.1, "source": "model" } ] ``` `key` is the opaque `connector|network|variant|funding|issuer|currency|ic_category` identifier used for the override calls below. `limit` defaults to 10, capped at 50. ### Set A Cluster Fee Override ```bash theme={null} curl --request PUT \ "$BASE_URL/merchant-account/merchant_demo/cost-clusters/adyen%7Cvisa%7Ccredit%7Ccredit%7Cus%7Cusd%7Cdomestic/fee-override" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "pct_bps": 165.0, "fixed": 0.1 }' ``` ### Delete A Cluster Fee Override ```bash theme={null} curl --request DELETE \ "$BASE_URL/merchant-account/merchant_demo/cost-clusters/adyen%7Cvisa%7Ccredit%7Ccredit%7Cus%7Cusd%7Cdomestic/fee-override" \ --header "$AUTH_HEADER" ``` The `|` separators in `key` must be URL-encoded (`%7C`) when used as a path segment. ## Cost Coverage Cost-aware routing is only as good as the cost data behind it. A fitted model is trustworthy for some clusters and shaky for others, and routing decisions made on a shaky estimate can do more harm than good. **Cost coverage is the honesty check**: it tells you what fraction of a merchant's real volume actually has a cost model solid enough to route on, so you know whether to lean on multi-objective routing or hold off until more settlement data arrives. Every fitted cluster is graded with one of three verdicts: * **`GOOD`** — enough transactions (`n ≥ 200`) and a tight linear fit (per-transaction error `bps_rmse ≤ 15`). These are the clusters cost routing trusts. * **`THIN`** — too little settlement volume to fit confidently yet. More data over time promotes these to `GOOD`. * **`NON_LINEAR`** — plenty of data, but the fee doesn't follow a clean `pct × amount + fixed` line (tiered pricing, surcharges, mixed assessments), so the linear estimate isn't reliable. Coverage is reported by **volume (money), not by cluster count**, because that's what matters economically: a merchant can have hundreds of tiny `THIN` clusters that together carry a rounding error of GMV. `good_gross_pct` — the share of settled *value* sitting in `GOOD` clusters — is therefore the headline number. Everything outside a `GOOD` cluster simply falls back to plain success-rate routing, so a low coverage figure doesn't break routing; it just means fewer payments get the cost lens. As a rule of thumb, wait for `good_gross_pct` to climb into a comfortable range before flipping the merchant-wide multi-objective flag. The raw fields: Answers "is cost estimation actually working for this merchant?" — the dashboard health-card summary. `good_gross_pct` (share of settled *volume* with a trustworthy model) is the headline number; everything not covered falls back to plain success-rate routing. ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/cost-coverage" \ --header "$AUTH_HEADER" ``` ```json theme={null} { "total_clusters": 214, "good_clusters": 178, "thin_clusters": 28, "non_linear_clusters": 8, "total_txns": 96430, "good_txns": 88112, "thin_txns": 6900, "non_linear_txns": 1418, "good_txn_pct": 91.4, "total_gross": 3182004.11, "good_gross": 2984502.9, "thin_gross": 154002.4, "non_linear_gross": 43498.81, "good_gross_pct": 93.79, "bps_rmse_p50": 2.1, "bps_rmse_p90": 6.4, "report_date": "2026-07-01" } ``` * `GOOD` clusters have enough consistent data to trust; `THIN` have too little volume; `NON_LINEAR` have a fee structure the linear fit can't capture well. * `bps_rmse_p50`/`p90` are the fit accuracy (basis-point error) of the `GOOD` clusters. ## Related * [Cost Ingestion: Connector Setup](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup) * [Cost Ingestion: Uploads](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads) * [Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) * [Analytics Endpoints](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints) — see Cost Savings for the merchant-facing rollup. # Cost Ingestion: Connector Setup Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup Curl examples for registering connector settlement credentials and receiving settlement webhooks — the entry point for cost data ingestion. # Cost Ingestion: Connector Setup Cost ingestion learns each connector's *actual* per-transaction fee (percentage + flat component) from real settlement reports and invoices, at a fine-grained cluster level (connector × card network × card variant × funding × issuer country × currency × interchange category). That fitted cost model is what [multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) ranks gateways on. ### Why it's learned, not configured Processor pricing is rarely a single number. The effective cost of a transaction depends on the card network, whether the card is credit or debit, where it was issued, the currency, and the interchange category — and published rate cards drift from what actually lands on the settlement statement once assessments, downgrades, and blended tiers are applied. Rather than ask a merchant to enter fee schedules by hand (which go stale the moment a processor re-prices), Decision Engine **reads the money that actually moved.** For each cluster it fits a simple linear model against real settlements — `fee ≈ pct_bps × amount + fixed` — using ordinary least squares. The slope becomes the percentage component (in basis points) and the intercept the flat per-transaction fee. That fitted `(pct_bps, fixed)` pair is the cost estimate every expected-value calculation uses. Because the fit is per-cluster, the model captures that (say) Visa credit issued in the US costs a different amount than a domestic debit card — precisely the differences that make one gateway cheaper for one slice of traffic and pricier for another. How much of a merchant's volume has a *trustworthy* fit (versus too little data, or a fee structure the linear model can't capture) is what [cost coverage](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees#cost-coverage) reports. Before any report or invoice can be ingested, register the connector account's settlement credentials. ## Data Sources Settlement data reaches Decision Engine through three paths, all feeding the same `cost_ingestion` pipeline: | Source | How it works | Docs | | - | - | - | | Webhook push | The connector calls Decision Engine when a report is ready. Verified via the stored `webhook_secret`, then queued. | This page | | Scheduled poll | A background job polls the connector's reporting API for ready reports. No merchant action needed once credentials are set. | This page | | Manual upload | Upload a report or invoice file directly — useful before webhooks are wired, for backfills, or testing. | [Uploads](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads) | ## Register Connector Credentials ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/credentials" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "account": "YOUR_ADYEN_MERCHANT_ACCOUNT_CODE", "webhook_secret": "whsec_...", "download_auth": "report_user:report_password" }' ``` * `account` — the connector-side account (e.g. Adyen's `merchantAccountCode`). * `webhook_secret` — used to verify inbound webhook signatures for this account. * `download_auth` — credential used to authenticate report downloads for the scheduled poller. Either `"user:password"` for Basic auth, or a bare API key (sent as `X-API-Key`). Response: ```json theme={null} { "merchant_id": "merchant_demo", "connector": "adyen", "account": "YOUR_ADYEN_MERCHANT_ACCOUNT_CODE", "status": "saved" } ``` Secrets are encrypted at rest and never returned by the API — subsequent reads only return masked hints. ## List Configured Connectors ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/connectors" \ --header "$AUTH_HEADER" ``` ```json theme={null} [ { "connector": "adyen", "account": "YOUR_ADYEN_MERCHANT_ACCOUNT_CODE", "webhook_secret_hint": "••••af31", "download_auth_hint": "report_user:••••" } ] ``` ## Remove Credentials ```bash theme={null} curl --request DELETE \ "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/credentials/YOUR_ADYEN_MERCHANT_ACCOUNT_CODE" \ --header "$AUTH_HEADER" ``` Returns `204 No Content`. Deleting a source that isn't configured also returns success (idempotent). ## Settlement Webhook (Connector → Decision Engine) Once credentials are registered, point the connector's settlement-report notification at: ``` POST /webhooks/settlement/:connector ``` This route is **public** (no `AUTH_HEADER`) — the connector authenticates itself via its own signature, which Decision Engine verifies against the `webhook_secret` stored for that `(connector, account)` pair. Adyen is the first supported connector (`:connector = adyen`). ```bash theme={null} curl --location "$BASE_URL/webhooks/settlement/adyen" \ --header "Content-Type: application/json" \ --data @adyen-settlement-notification.json ``` The handler ACKs immediately and enqueues the report for background processing — download, parse, and re-fit all happen asynchronously in the ingest worker, so the connector always gets a fast response. A bad signature returns `401`; an unrecognized connector or malformed payload returns `400`. ## Notes * Manual and webhook/poll-based ingestions share the same pipeline and history — see [Uploads](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads) for the manual path and ingestion history. * Once enough settlement data has been fitted, check [Cost Coverage](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees#cost-coverage) to see what share of volume has a trustworthy cost model. ## Related * [Cost Ingestion: Uploads](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads) * [Cost Ingestion: Fees & Coverage](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees) * [Multi-Objective Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) # Cost Ingestion: Uploads Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-uploads Curl examples for manually uploading settlement reports and invoices, and inspecting ingestion history. # Cost Ingestion: Uploads Use manual upload when webhooks aren't wired yet, for backfilling historical data, or for testing. Manual uploads share the same `cost_ingestion` pipeline and history as webhook- and poll-based ingestion (see [Connector Setup](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup)). ## Upload A Settlement Report Settlement reports can run to several GB, so the request body is streamed straight to disk and processed in the background — the request returns immediately with a job id to poll. ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/report?account=YOUR_ADYEN_MERCHANT_ACCOUNT_CODE" \ --header "$AUTH_HEADER" \ --header "Content-Type: text/csv" \ --data-binary @settlement-report.csv ``` Returns `202 Accepted` immediately: ```json theme={null} { "id": "ing_8f21a6c0", "status": "processing" } ``` Upload is capped at 8 GiB per file. ## Check Ingestion History Poll to see history and in-flight progress, newest first: ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/cost-ingestions" \ --header "$AUTH_HEADER" ``` ```json theme={null} [ { "id": "ing_8f21a6c0", "connector": "adyen", "account": "YOUR_ADYEN_MERCHANT_ACCOUNT_CODE", "source": "manual", "status": "completed", "staged_rows": 48213, "report_date": "2026-07-01", "period_start": "2026-06-01", "period_end": "2026-06-30", "currency_count": 3, "currencies": ["USD", "EUR", "GBP"], "country_count": 12, "countries": ["US", "GB", "DE"], "total_gross": 1284302.55, "total_clusters": 214, "good_clusters": 178, "last_error": null, "created_at": "2026-07-01T03:12:44Z" } ] ``` `source` is `"manual"`, `"webhook"`, or `"poll"` depending on how the report arrived. `status` is `"processing"`, `"completed"`, or `"failed"` (see `last_error`). ## Delete An Ingestion Removes the transactions that ingestion contributed, re-fits the affected connector/account so the served cost model reflects the deletion, and deletes the history row. ```bash theme={null} curl --request DELETE \ "$BASE_URL/merchant-account/merchant_demo/cost-ingestions/ing_8f21a6c0" \ --header "$AUTH_HEADER" ``` Returns `204 No Content`. Returns `409 Conflict` if the ingestion is still `processing`. ## Detect Price Changes Surfaces fee-regime changes detected by diffing each cluster's two most recent fits — useful for noticing when a connector silently repriced. ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/cost-price-changes" \ --header "$AUTH_HEADER" ``` ## Upload An Invoice Invoices are small (a few hundred lines) and processed synchronously — the computed cost add-on is returned directly in the response. Use this to recover invoice-only fees (e.g. periodic/flat fees) that a settlement report alone doesn't capture. ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/invoice?account=YOUR_ADYEN_MERCHANT_ACCOUNT_CODE&invoice_ref=INV-2026-06" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/pdf" \ --data-binary @adyen-invoice-june.pdf ``` ```json theme={null} { "merchant_id": "merchant_demo", "connector": "adyen", "account": "YOUR_ADYEN_MERCHANT_ACCOUNT_CODE", "pct_addon_bps": 2.4, "fixed_addon": 0.01, "total_addon_per_txn": 0.034, "subtotal_ex_tax": 4820.55, "card_volume": 1284302.55, "txn_count": 48213, "currency": "EUR", "lines": 6, "breakdown": [ { "description": "Monthly platform fee", "kind": "flat_per_txn", "added": true, "amount": 500.0, "per_txn": 0.0104 }, { "description": "Interchange (already in settlement data)", "kind": "already_modeled", "added": false, "amount": 3200.0, "per_txn": 0.0 } ] } ``` Invoice uploads are capped at 32 MiB. `breakdown[].added` is `true` for fee lines this add-on newly captures, `false` for lines already reflected in the settlement-report model (e.g. interchange) or ignored (volume-only lines). ## List Invoice Add-Ons ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/invoice-addons" \ --header "$AUTH_HEADER" ``` ## Delete An Invoice Add-On Reverts the merchant's served cost model to the learned-only (settlement-report-based) cost. ```bash theme={null} curl --request DELETE \ "$BASE_URL/merchant-account/merchant_demo/connectors/adyen/invoice-addon" \ --header "$AUTH_HEADER" ``` Returns `204 No Content`. ## Invoice Reconciliation Ties each stored invoice add-on back to coverage before/after, so you can see how much of the invoice's cost is now explained by the model. ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/invoice-reconciliation" \ --header "$AUTH_HEADER" ``` ## Related * [Cost Ingestion: Connector Setup](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup) * [Cost Ingestion: Fees & Coverage](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees) # Update Gateway Score Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/feedback-scoring/update-gateway-score Curl example for /update-gateway-score. # Update Gateway Score Call this after non-debit runtime payments so SR data stays current. Do not call it for `NTW_BASED_ROUTING` debit runs where `decided_gateway` is not the selected network. ## Request ```bash theme={null} curl --location "$BASE_URL/update-gateway-score" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "gateway": "stripe", "gatewayReferenceId": null, "status": "CHARGED", "paymentId": "sr_001", "enforceDynamicRoutingFailure": null }' ``` ## Response ```text theme={null} Success ``` # Health Checks Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/health-status/health-check Curl examples for /health, /health/ready, and /health/diagnostics. # Health Checks Health routes are public and do not require `AUTH_HEADER`. `/health/diagnostics` is the one exception — it needs `x-tenant-id`, see below. ## Liveness ```bash theme={null} curl "$BASE_URL/health" ``` ```json theme={null} { "message": "Health is good" } ``` ## Readiness ```bash theme={null} curl "$BASE_URL/health/ready" ``` ```json theme={null} { "message": "Up" } ``` ## Diagnostics Unlike `/health` and `/health/ready`, this route resolves a tenant and requires `x-tenant-id` — omitting it fails with `TE_03: x-tenant-id not found in headers` even though no `AUTH_HEADER` is needed. `public` is the only tenant the shipped config files define. ```bash theme={null} curl "$BASE_URL/health/diagnostics" \ --header "x-tenant-id: public" ``` ```json theme={null} { "key_custodian_locked": false, "database": { "database_connection": "Working", "database_read": "Working", "database_write": "Working", "database_delete": "Working" } } ``` # Legacy Decision Gateway Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/legacy/decision-gateway-legacy Compatibility example for the legacy /decision_gateway route. # Legacy Decision Gateway `/decision_gateway` is retained for compatibility with older integrations. New integrations should use [`/decide-gateway`](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-sr-based). ```bash theme={null} curl --location "$BASE_URL/decision_gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen"], "rankingAlgorithm": "SR_BASED_ROUTING", "paymentInfo": { "paymentId": "legacy_001", "amount": 1000, "currency": "USD", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT" } }' ``` # Legacy Update Score Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/legacy/update-score-legacy Compatibility example for the legacy /update-score route. # Legacy Update Score `/update-score` is retained for compatibility. New integrations should use [`/update-gateway-score`](/decision-engine-api-reference/api-reference/guides/feedback-scoring/update-gateway-score). ```bash theme={null} curl --location "$BASE_URL/update-score" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "gateway": "stripe", "paymentId": "pay_001", "status": "CHARGED" }' ``` # Create Merchant Account Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/merchant-accounts/merchant-account-create Curl example for creating a merchant account. # Create Merchant Account This public bootstrap route requires the configured admin secret. ## Request ```bash theme={null} curl --location "$BASE_URL/merchant-account/create" \ --header "x-admin-secret: " \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "gateway_success_rate_based_decider_input": null }' ``` ## Response ```json theme={null} { "message": "Merchant account created successfully", "merchant_id": "merchant_demo", "gateway_success_rate_based_decider_input": null, "api_key": "DE_..." } ``` # Delete Merchant Account Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/merchant-accounts/merchant-account-delete Curl example for deleting a merchant account. # Delete Merchant Account ## Request ```bash theme={null} curl --request DELETE "$BASE_URL/merchant-account/merchant_demo" \ --header "$AUTH_HEADER" ``` ## Response ```json theme={null} { "message": "Merchant account deleted successfully", "merchant_id": "merchant_demo" } ``` # Get Merchant Account Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/merchant-accounts/merchant-account-get Curl example for retrieving a merchant account. # Get Merchant Account ## Request ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo" \ --header "$AUTH_HEADER" ``` ## Response ```json theme={null} { "merchant_id": "merchant_demo", "gateway_success_rate_based_decider_input": null } ``` # Merchant Debit Routing Flag Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/merchant-accounts/merchant-debit-routing Curl examples for reading and updating the merchant debit-routing feature flag. # Merchant Debit Routing Flag Debit/network routing is gated per merchant. Missing config defaults to disabled. Enable this flag before calling `/decide-gateway` with `NTW_BASED_ROUTING` or `NTW_SR_HYBRID_ROUTING`. ## Read Flag ```bash theme={null} curl "$BASE_URL/merchant-account/merchant_demo/debit-routing" \ --header "$AUTH_HEADER" ``` ```json theme={null} { "merchant_id": "merchant_demo", "debit_routing_enabled": false } ``` ## Enable Flag ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/debit-routing" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "enabled": true }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "debit_routing_enabled": true } ``` ## Disable Flag ```bash theme={null} curl --location "$BASE_URL/merchant-account/merchant_demo/debit-routing" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "enabled": false }' ``` ## Run Debit Routing Transaction After enabling the flag, send a debit card transaction through `/decide-gateway`. The debit router expects `paymentInfo.metadata` to be a JSON string containing `merchant_category_code`, `acquirer_country`, and `co_badged_card_data`. ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen"], "rankingAlgorithm": "NTW_BASED_ROUTING", "paymentInfo": { "paymentId": "debit_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "DEBIT", "authType": "THREE_DS", "metadata": "{\"merchant_category_code\":\"merchant_category_code_0001\",\"acquirer_country\":\"US\",\"co_badged_card_data\":{\"card_type\":\"debit\",\"issuer_country\":\"US\",\"is_regulated\":false,\"regulated_name\":null,\"card_networks\":[\"VISA\",\"NYCE\",\"PULSE\",\"STAR\"]}}" } }' ``` ```json theme={null} { "decided_gateway": "stripe", "routing_approach": "NTW_BASED_ROUTING", "debit_routing_output": { "co_badged_card_networks_info": [ { "network": "NYCE", "saving_percentage": 1.2 }, { "network": "PULSE", "saving_percentage": 0.8 } ], "issuer_country": "US", "is_regulated": false, "card_type": "debit" } } ``` ## Notes * Use backend enum strings: `NTW_BASED_ROUTING` and `NTW_SR_HYBRID_ROUTING`. * `co_badged_card_data.card_type` must be lowercase `debit` or `credit` inside metadata. * If the flag is disabled, debit-routing transactions should fail with a debit-routing-not-enabled error. ## Related * [Debit Gateway Transaction](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-debit-routing) * [Network + SR Hybrid Routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-hybrid-routing) * [Payment Audit](/decision-engine-api-reference/api-reference/guides/analytics-audit/analytics-endpoints) # Decide Gateway: Debit Routing Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-debit-routing Curl example for /decide-gateway using NTW_BASED_ROUTING. # Decide Gateway: Debit Routing Enable the merchant debit-routing flag before this call. The backend reads debit inputs from `paymentInfo.metadata`, so `metadata` must be a JSON string with `co_badged_card_data`. ## Request ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen"], "rankingAlgorithm": "NTW_BASED_ROUTING", "eliminationEnabled": false, "enableMultiObjective": false, "paymentInfo": { "paymentId": "debit_001", "amount": 1000, "currency": "USD", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "DEBIT", "authType": "THREE_DS", "metadata": "{\"merchant_category_code\":\"merchant_category_code_0001\",\"acquirer_country\":\"US\",\"co_badged_card_data\":{\"co_badged_card_networks\":[\"VISA\",\"NYCE\",\"PULSE\",\"STAR\"],\"issuer_country\":\"US\",\"is_regulated\":false,\"regulated_name\":null,\"card_type\":\"debit\"}}" } }' ``` ## Response ```json theme={null} { "decided_gateway": "stripe", "gateway_priority_map": null, "filter_wise_gateways": null, "priority_logic_tag": null, "routing_approach": "NTW_BASED_ROUTING", "gateway_before_evaluation": null, "priority_logic_output": null, "debit_routing_output": { "co_badged_card_networks_info": [ { "network": "NYCE", "saving_percentage": 1.2 }, { "network": "PULSE", "saving_percentage": 0.9 }, { "network": "VISA", "saving_percentage": 0.1 } ], "issuer_country": "US", "is_regulated": false, "regulated_name": null, "card_type": "debit" }, "reset_approach": "NO_RESET", "routing_dimension": null, "routing_dimension_level": null, "is_scheduled_outage": false, "is_dynamic_mga_enabled": false, "gateway_mga_id_map": null, "is_rust_based_decider": true, "multi_objective_info": null } ``` ## Multi-Objective Option When multi-objective routing is enabled (request field `enableMultiObjective`, or the `multi_objective_routing_enabled` merchant feature flag), a cost-aware post-step may re-rank the SR result and the response gains a `multi_objective_info` block. Details and examples: [Multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). # Decide Gateway: Network + SR Hybrid Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-hybrid-routing Curl example for /decide-gateway using NTW_SR_HYBRID_ROUTING. # Decide Gateway: Network + SR Hybrid `NTW_SR_HYBRID_ROUTING` combines debit/network metadata with SR-based gateway scoring. ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen"], "rankingAlgorithm": "NTW_SR_HYBRID_ROUTING", "eliminationEnabled": false, "enableMultiObjective": false, "paymentInfo": { "paymentId": "hybrid_001", "amount": 1000, "currency": "USD", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "DEBIT", "authType": "THREE_DS", "metadata": "{\"merchant_category_code\":\"merchant_category_code_0001\",\"acquirer_country\":\"US\",\"co_badged_card_data\":{\"co_badged_card_networks\":[\"VISA\",\"NYCE\",\"PULSE\",\"STAR\"],\"issuer_country\":\"US\",\"is_regulated\":false,\"regulated_name\":null,\"card_type\":\"debit\"}}" } }' ``` ```json theme={null} { "decided_gateway": "stripe", "routing_approach": "NTW_BASED_ROUTING", "debit_routing_output": { "co_badged_card_networks_info": [ { "network": "NYCE", "saving_percentage": 1.2 }, { "network": "PULSE", "saving_percentage": 0.9 } ], "issuer_country": "US", "is_regulated": false, "regulated_name": null, "card_type": "debit" }, "multi_objective_info": null } ``` ## Multi-Objective Option When multi-objective routing is enabled (request field `enableMultiObjective`, or the `multi_objective_routing_enabled` merchant feature flag), a cost-aware post-step may re-rank the SR result and the response gains a `multi_objective_info` block. Details and examples: [Multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). # Decide Gateway: Multi-Objective Routing Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective Curl example for /decide-gateway with the multi-objective (cost-aware) post-step and the multi_objective_info response block. # Decide Gateway: Multi-Objective Routing ## What multi-objective routing is Plain success-rate (SR) routing optimises a single objective: send each payment to the gateway most likely to authorise it. But the *cheapest* path to a successful payment is not always the one with the highest auth rate — a gateway that is one point worse on auth but materially cheaper per transaction can leave the merchant with more money in hand. Multi-objective routing balances **two** objectives at once — authorisation *and* processing cost — so routing maximises the merchant's economic outcome, not just the raw approval odds. It is implemented as a **cost-aware post-step layered on top of SR scoring**, not a replacement for it. The SR scorer runs first and produces its usual ranking; the post-step then takes those scores, attaches a per-gateway fee estimate to each, and re-ranks the candidates on expected value. Because it only ever runs *after* SR scoring, everything SR gives you (dimension-level buckets, elimination, hedging) is preserved — cost is simply an additional lens applied at the end. ## How the ranking works After the success-rate scorer picks its head gateway, the engine fetches per-PSP fee estimates and re-ranks every gateway that has cost data on economic value: ``` Economic value (EV) = auth rate × settlement value settlement value = txn amount − cost of payment processing (acquirer, issuer & network fee) ``` The settlement value is derived from the merchant's `margin` and the per-PSP cost estimate (see the `margin` field on [Create success-rate config](/decision-engine-api-reference/api-reference/guides/scoring-config/success-rate-config-create)). If a cheaper PSP has a strictly higher expected value than the SR head, it is promoted (`outcome: COST_WON`) and `routing_approach` becomes `SR_SELECTION_MULTI_OBJECTIVE`. Otherwise the SR head is kept (`outcome: AUTH_WON`) and `routing_approach` keeps its normal SR value. Either way, the response carries a `multi_objective_info` block explaining the decision — which gateway SR would have picked, which one cost analysis chose, and by how much — so every cost-driven override is auditable. ## Enablement | Switch | Scope | Behaviour | | - | - | - | | `multi_objective_routing_enabled` feature flag | Merchant | Primary rollout switch. Used whenever the request omits `enableMultiObjective`. | | `enableMultiObjective` request field | Per request | Optional boolean override. `true` forces the post-step on, `false` forces it off, omitted falls back to the merchant flag. | Notes: * The post-step only runs on SR-scored decisions and is skipped while hedging (exploration) is active for the transaction. * `margin` (fraction of ticket, e.g. `0.20`) comes from the merchant's success-rate config — see [Create success-rate config](/decision-engine-api-reference/api-reference/guides/scoring-config/success-rate-config-create). It defaults to `1.0` when unset. * This post-step re-ranks the SR scores it is handed; it does not tune them. [Autopilot](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features) is the separate self-tuning job that calibrates SR hedging and bucket size, and can run alongside this post-step (they are independent dials — `enableMultiObjective` and `use_autopilot`). * Gateways without fee data cannot be ranked on expected value and never win on cost; if the SR head itself has no fee data, the SR order is kept. * Per-gateway fee data comes from [cost ingestion](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-setup) — settlement reports and invoices fitted into a per-cluster cost model. Check [cost coverage](/decision-engine-api-reference/api-reference/guides/cost-ingestion/cost-ingestion-fees#cost-coverage) to see what share of volume actually has a trustworthy fee estimate before relying on this post-step. * To compare cost-aware routing against a plain auth-rate baseline on live traffic before flipping the merchant flag, run it as an [A/B test experiment](/decision-engine-api-reference/api-reference/guides/ab-testing/ab-testing-create) arm (`enable_multi_objective: true` on one arm only). ## Request ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen", "checkout"], "rankingAlgorithm": "SR_BASED_ROUTING", "eliminationEnabled": true, "enableMultiObjective": true, "paymentInfo": { "paymentId": "mo_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "metadata": null, "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS", "cardIsin": "424242" } }' ``` ## Response: cost won `adyen` is promoted over the SR head `stripe` because its expected value is higher at the configured margin; fallbacks are re-ordered by descending expected value (gateways without fee data follow, ordered by auth rate). ```json theme={null} { "decided_gateway": "adyen", "fallback_gateways": ["stripe", "checkout"], "gateway_priority_map": { "stripe": 0.94, "adyen": 0.91, "checkout": 0.88 }, "filter_wise_gateways": null, "priority_logic_tag": null, "routing_approach": "SR_SELECTION_MULTI_OBJECTIVE", "gateway_before_evaluation": "stripe", "reset_approach": "NO_RESET", "routing_dimension": "ORDER_PAYMENT,CARD,CREDIT,UNKNOWN", "routing_dimension_level": "CARD_LEVEL", "is_scheduled_outage": false, "is_dynamic_mga_enabled": false, "gateway_mga_id_map": null, "is_rust_based_decider": true, "multi_objective_info": { "outcome": "COST_WON", "reason": "Promoted 'adyen' over 'stripe' on expected value — saves 80.00 bps for 3.00pp auth.", "srHead": { "psp": "stripe", "authRate": 0.94, "costBps": 180.0 }, "chosen": { "psp": "adyen", "authRate": 0.91, "costBps": 100.0 }, "costSavedBps": 80.0, "qualifiedCount": 3, "margin": 0.2, "evGapTop2": 0.00182 } } ``` ## Response: auth won The post-step ran but the SR head was already the highest expected-value gateway, so nothing moves and `routing_approach` keeps its normal SR value. Note `margin: 1` — the default applied when the merchant's success-rate config sets no `margin`. ```json theme={null} { "decided_gateway": "adyen", "fallback_gateways": [ "stripe", "checkout" ], "gateway_priority_map": { "adyen": 0.65, "checkout": 0.58, "stripe": 0.65 }, "filter_wise_gateways": null, "priority_logic_tag": null, "routing_approach": "SR_SELECTION_V3_ROUTING", "gateway_before_evaluation": "adyen", "priority_logic_output": { "isEnforcement": false, "gws": [ "stripe", "adyen", "checkout" ], "priorityLogicTag": null, "gatewayReferenceIds": {}, "primaryLogic": null, "fallbackLogic": null }, "debit_routing_output": null, "reset_approach": "NO_RESET", "routing_dimension": "ORDER_PAYMENT, CARD, DEBIT, DEBIT", "routing_dimension_level": "CARD_LEVEL", "is_scheduled_outage": false, "is_dynamic_mga_enabled": false, "gateway_mga_id_map": null, "is_rust_based_decider": true, "latency": 3, "multi_objective_info": { "outcome": "AUTH_WON", "reason": "SR head retained — it is the highest expected-value PSP (3 ranked on EV).", "srHead": { "psp": "adyen", "authRate": 0.65, "costBps": 156.94736842105263 }, "chosen": { "psp": "adyen", "authRate": 0.65, "costBps": 156.94736842105263 }, "costSavedBps": null, "qualifiedCount": 3, "margin": 1, "evGapTop2": 0.013780000000000014 } } ``` ## multi\_objective\_info Fields | Field | Type | Meaning | | - | - | - | | `outcome` | `COST_WON` \| `AUTH_WON` | Terminal outcome of the post-step. `COST_WON` means a higher-EV PSP was promoted above the SR head. | | `reason` | string | Human-readable explanation of the decision. | | `srHead` | object \| null | The PSP the SR scorer would have picked (`psp`, `authRate`, `costBps`). | | `chosen` | object \| null | The PSP the post-step actually chose. Equals `srHead` when auth won. | | `costSavedBps` | number \| null | Fee saved in bps when `outcome == COST_WON` (`srHead.costBps − chosen.costBps`). | | `qualifiedCount` | integer | Number of PSPs that had cost data and were ranked on expected value. | | `margin` | number | Merchant margin (fraction of ticket) applied for this transaction. | | `evGapTop2` | number \| null | Expected-value gap between the top-two EV-ranked PSPs, as a fraction of ticket. Small values mean the decision was close. `null` when fewer than two PSPs had cost data. | The block is absent (`null`) when the post-step did not run at all — feature off, hedging active, or a non-SR routing flavour. # Decide Gateway: Priority List Based Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-pl-based Curl example for /decide-gateway using PL_BASED_ROUTING. # Decide Gateway: Priority List Based `PL_BASED_ROUTING` evaluates active priority logic and returns the selected connector order. ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen", "checkout"], "rankingAlgorithm": "PL_BASED_ROUTING", "eliminationEnabled": false, "enableMultiObjective": false, "paymentInfo": { "paymentId": "pl_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS" } }' ``` ```json theme={null} { "decided_gateway": "stripe", "routing_approach": "PRIORITY_LOGIC", "priority_logic_output": { "isEnforcement": false, "gws": ["stripe", "adyen", "checkout"], "gatewayReferenceIds": {} }, "reset_approach": "NO_RESET", "multi_objective_info": null } ``` ## Multi-Objective Option When multi-objective routing is enabled (request field `enableMultiObjective`, or the `multi_objective_routing_enabled` merchant feature flag), a cost-aware post-step may re-rank the SR result and the response gains a `multi_objective_info` block. Details and examples: [Multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). # Decide Gateway: SR Based Routing Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-sr-based Curl example for /decide-gateway using SR_BASED_ROUTING. # Decide Gateway: SR Based Routing `SR_BASED_ROUTING` uses auth-rate history, downtime state, and eligible gateway filters to choose a connector. ## Request ```bash theme={null} curl --location "$BASE_URL/decide-gateway" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchantId": "merchant_demo", "eligibleGatewayList": ["stripe", "adyen", "checkout"], "rankingAlgorithm": "SR_BASED_ROUTING", "eliminationEnabled": true, "enableMultiObjective": false, "paymentInfo": { "paymentId": "sr_001", "amount": 1000, "currency": "USD", "country": "US", "paymentType": "ORDER_PAYMENT", "metadata": null, "paymentMethodType": "CARD", "paymentMethod": "CREDIT", "authType": "THREE_DS", "cardIsin": "424242" } }' ``` ## Response ```json theme={null} { "decided_gateway": "stripe", "gateway_priority_map": { "stripe": 0.94, "adyen": 0.91, "checkout": 0.88 }, "filter_wise_gateways": null, "priority_logic_tag": null, "routing_approach": "SR_SELECTION_V3_ROUTING", "gateway_before_evaluation": "stripe", "priority_logic_output": { "isEnforcement": false, "gws": ["stripe", "adyen", "checkout"], "priorityLogicTag": null, "gatewayReferenceIds": {}, "primaryLogic": null, "fallbackLogic": null }, "reset_approach": "NO_RESET", "routing_dimension": "ORDER_PAYMENT,CARD,CREDIT,UNKNOWN", "routing_dimension_level": "CARD_LEVEL", "is_scheduled_outage": false, "is_dynamic_mga_enabled": false, "gateway_mga_id_map": null, "is_rust_based_decider": true, "multi_objective_info": null } ``` ## Routing Approach Values * `SR_SELECTION_V3_ROUTING`: best eligible gateway from SR score at the active routing dimension. * `SR_V3_DOWNTIME_ROUTING`: some eligible gateways were deprioritized due to downtime. * `SR_V3_ALL_DOWNTIME_ROUTING`: all eligible gateways are in downtime and the best degraded option is selected. * `SR_V3_HEDGING`: exploration mode across eligible gateways. * `SR_V3_DOWNTIME_HEDGING`: hedging with partial downtime. * `SR_V3_ALL_DOWNTIME_HEDGING`: hedging while all eligible gateways are down. * `SR_SELECTION_MULTI_OBJECTIVE`: the multi-objective post-step promoted a cheaper gateway over the SR head on expected value — see [Multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). ## Multi-Objective Option When multi-objective routing is enabled (request field `enableMultiObjective`, or the `multi_objective_routing_enabled` merchant feature flag), a cost-aware post-step may re-rank the SR result and the response gains a `multi_objective_info` block. Details and examples: [Multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective). # Routing Config Endpoints Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/config-endpoints Curl examples for routing key metadata and SR dimension configuration. # Routing Config Endpoints ## Routing Keys The dashboard uses this route to discover valid rule builder keys. ```bash theme={null} curl "$BASE_URL/config/routing-keys" \ --header "$AUTH_HEADER" ``` ## Configure SR Dimensions ```bash theme={null} curl --location "$BASE_URL/config-sr-dimension" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "dimensions": ["payment_method_type", "payment_method", "currency"] }' ``` ## Get SR Dimensions Read back the SR scoring dimensions currently configured for a merchant. ```bash theme={null} curl "$BASE_URL/config-sr-dimension/merchant_demo" \ --header "$AUTH_HEADER" ``` ```json theme={null} { "merchant_id": "merchant_demo", "paymentInfo": { "udfs": [], "fields": ["payment_method_type", "payment_method", "currency"] } } ``` Returns an empty default (`fields: null`) when nothing has been configured for the merchant yet. ## GSM Options Gateway Status Mapper rule catalog — the error-code classification options used by the `gsm-scoring-filter` merchant feature (see [Merchant Features](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features)). ```bash theme={null} curl "$BASE_URL/gsm/options" \ --header "$AUTH_HEADER" ``` ```json theme={null} { "rules": [ { "connector": "stripe", "flow": "authorize", "subFlow": "card", "errorCode": "card_declined", "errorMessage": "Your card was declined.", "errorCategory": "soft_decline", "unifiedCode": "UE_001", "unifiedMessage": "Card declined by issuer", "decision": "retry" } ] } ``` # Create Elimination Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/elimination-config-create Curl example for creating elimination config. # Create Elimination Config ```bash theme={null} curl --location "$BASE_URL/rule/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "config": { "type": "elimination", "data": { "bucketSize": 5, "eliminationThreshold": 0.2 } } }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "config": { "type": "elimination" } } ``` # Delete Elimination Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/elimination-config-delete Curl example for deleting elimination config. # Delete Elimination Config ```bash theme={null} curl --location "$BASE_URL/rule/delete" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "algorithm": "elimination" }' ``` ```json theme={null} { "message": "Rule config deleted successfully" } ``` # Get Elimination Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/elimination-config-get Curl example for reading elimination config. # Get Elimination Config ```bash theme={null} curl --location "$BASE_URL/rule/get" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "algorithm": "elimination" }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "config": { "type": "elimination" } } ``` # Update Elimination Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/elimination-config-update Curl example for updating elimination config. # Update Elimination Config ```bash theme={null} curl --location "$BASE_URL/rule/update" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "config": { "type": "elimination", "data": { "bucketSize": 10, "eliminationThreshold": 0.15 } } }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "config": { "type": "elimination" } } ``` # Create Success Rate Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/success-rate-config-create Curl example for creating success-rate scoring config. # Create Success Rate Config Success-rate (SR) routing is Decision Engine's default scoring strategy: for each payment it estimates how likely every eligible gateway is to authorise *right now* and sends the payment to the strongest one. The estimate is not a static number — it is learned continuously from the live outcomes (success/failure) the engine observes, so the routing follows real-time gateway health instead of a fixed priority list. The success-rate config is where you tune how that learning behaves. Three knobs do most of the work: * **`defaultBucketSize`** — how many of the most recent transactions per gateway the score is computed over. A small bucket reacts fast to a gateway going down but is noisier; a large bucket is stable but slower to notice change. This is a sliding window: new outcomes push old ones out, so the score always reflects recent behaviour. * **`defaultHedgingPercent`** — the share of traffic deliberately *explored* away from the current best gateway. Without exploration the engine would starve non-leading gateways of traffic and never learn that they have recovered; hedging keeps every candidate's score fresh. (This is the same dial [Autopilot](/decision-engine-api-reference/api-reference/guides/autopilot/merchant-features) tunes automatically.) * **`defaultLatencyThreshold`** — optional latency ceiling used when penalising slow gateways. You can override any of these per traffic segment via **`subLevelInputConfig`** — keyed by dimensions such as `paymentMethodType`, card network, currency, or country — so a merchant can, for example, run a larger bucket for high-volume card traffic and a smaller one for a thin wallet segment. Anything not overridden falls back to the `default*` values. ```bash theme={null} curl --location "$BASE_URL/rule/create" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "config": { "type": "successRate", "data": { "defaultBucketSize": 20, "defaultLatencyThreshold": null, "defaultHedgingPercent": null, "margin": 0.20, "subLevelInputConfig": { "paymentMethodType": { "CARD": { "bucketSize": 30, "hedgingPercent": 0.05 } } } } } }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "config": { "type": "successRate" } } ``` `margin` is the merchant margin as a fraction of ticket (e.g. `0.20` for 20%). It feeds the [multi-objective routing](/decision-engine-api-reference/api-reference/guides/run-transactions/decide-gateway-multi-objective) economic-value ranking `EV = auth rate × settlement value` (settlement value = txn amount − cost of payment processing) by setting the merchant's share of the ticket, and defaults to `1.0` when unset. # Delete Success Rate Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/success-rate-config-delete Curl example for deleting success-rate scoring config. # Delete Success Rate Config ```bash theme={null} curl --location "$BASE_URL/rule/delete" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "algorithm": "successRate" }' ``` ```json theme={null} { "message": "Rule config deleted successfully" } ``` # Get Success Rate Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/success-rate-config-get Curl example for reading success-rate scoring config. # Get Success Rate Config ```bash theme={null} curl --location "$BASE_URL/rule/get" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "algorithm": "successRate" }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "config": { "type": "successRate" } } ``` # Update Success Rate Config Source: https://api-reference.hyperswitch.io/decision-engine-api-reference/api-reference/guides/scoring-config/success-rate-config-update Curl example for updating success-rate scoring config. # Update Success Rate Config ```bash theme={null} curl --location "$BASE_URL/rule/update" \ --header "$AUTH_HEADER" \ --header "Content-Type: application/json" \ --data '{ "merchant_id": "merchant_demo", "config": { "type": "successRate", "data": { "defaultBucketSize": 30, "defaultLatencyThreshold": 2500, "defaultHedgingPercent": 0.1 } } }' ``` ```json theme={null} { "merchant_id": "merchant_demo", "config": { "type": "successRate" } } ```