---
title: "Decide routing"
method: POST
path: "/decide"
tags: ["Routing Rules"]
---

# Decide routing

`POST /decide`

## Request

- Base URL: `http://localhost:8080`
- URL: `http://localhost:8080/decide`
- Auth: one of:
  - HTTP bearer
  - API key in header `x-api-key`

Evaluate the existing hybrid routing pipeline using the flat request contract. Existing rule evaluation, SR feature gates, A/B experiments and fallback behavior apply.

## Request body

- DecideRequest
  - `payment_id` string, required
  - `amount` integer, required: Amount in currency minor units; supplies both existing amount and payment_amount rule keys and the dynamic payment amount.
  - `currency` string, required: Currency code, e.g. USD.
  - `payment_method_type` string, nullable: Payment method family, e.g. card.
  - `payment_method_sub_type` string, nullable: Payment method subtype, e.g. credit.
  - `authentication_type` string, nullable
  - `capture_method` string, nullable
  - `mandate_type` string, nullable
  - `mandate_acceptance_type` string, nullable
  - `payment_type` string, nullable: The `payment_type` rule key: `normal`, `new_mandate`, `update_mandate`, `setup_mandate`, `recurring_mandate`, `non_mandate` or `ppt_mandate`. A rule that tests `payment_type` matches only when it is sent.
  - `setup_future_usage` string, nullable
  - `transaction_initiator` string, nullable
  - `surcharge_amount` integer, nullable: Amount in currency minor units.
  - `business_country` string, nullable: ISO 3166 alpha-2 country code.
  - `billing_country` string, nullable: ISO 3166 alpha-2 country code.
  - `business_label` string, nullable
  - `card` DecideCard, nullable
    - `card_isin` string, nullable
    - `card_extended_bin` string, nullable
    - `card_network` string, nullable
    - `card_type` string, nullable
    - `card_issuer` string, nullable
    - `card_issuing_country_code` string, nullable
    - `card_subtype` string, nullable
    - `card_discovery` string, nullable
    - `card_switch_provider` string, nullable
  - `customer_device_platform` string, nullable
  - `customer_device_type` string, nullable
  - `customer_device_display_size` string, nullable
  - `pay_later` string, nullable
  - `wallet` string, nullable
  - `upi` string, nullable
  - `voucher` string, nullable
  - `bank_redirect` string, nullable
  - `bank_debit` string, nullable
  - `bank_transfer` string, nullable
  - `real_time_payment` string, nullable
  - `gift_card` string, nullable
  - `card_redirect` string, nullable
  - `open_banking` string, nullable
  - `mobile_payment` string, nullable
  - `crypto` string, nullable
  - `reward` string, nullable
  - `network_token` string, nullable
  - `metadata` object, nullable
  - `country` string, nullable: ISO 3166 alpha-2 country code.
  - `customer_id` string, nullable
  - `routing_config` DecideRoutingConfig, required
    - `algorithm_for` string, required
    - `elimination_enabled` boolean, nullable
    - `enable_multi_objective` boolean, nullable
    - `ranking_algorithm` 'SR_BASED_ROUTING' | 'PL_BASED_ROUTING' | 'NTW_BASED_ROUTING' | 'NTW_SR_HYBRID_ROUTING' | 'null', nullable
    - `eligible_connectors` DecideConnector[], required
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable: The connector account. Omit it (or send null) to name the connector by gateway alone, as a hybrid fallback_output entry without gateway_id does; scores are then keyed by the gateway name.
    - `preferred_connectors` DecideConnector[], nullable
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable: The connector account. Omit it (or send null) to name the connector by gateway alone, as a hybrid fallback_output entry without gateway_id does; scores are then keyed by the gateway name.
  - `merchant_id` string, required: Routing scope previously supplied as created_by. Use the same identifier, including the HS profile ID where applicable.

## Response `200`

Routing decision. Connector order and account IDs are preserved from hybrid routing. An account ID can be null when a legacy rule identifies only a gateway.

- DecideResponse
  - `id` string, required: Unique per decision (`dec_` + a time-ordered UUID), so a retried payment's decisions stay apart.
  - `payment_id` string, required
  - `request_id` string, required: The `x-request-id` of the call, or the one minted for it. Matches the response header.
  - `created_at` string, date-time, required
  - `connectors` DecideResultConnector[], required: The order to try connectors in: the first is the choice, the rest the retry order. Empty when no connector is left.
    - `gateway_name` string, required
    - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
  - `outcome` DecideOutcome, required: How the order was reached. New values may be added to each enum; treat unknown values as their nearest documented meaning.
    - `type` 'routed' | 'fallback' | 'no_connector', required
    - `strategy` 'rule' | 'success_rate' | 'cost' | 'volume_commitment' | 'debit_network' | 'candidate_order' | 'none', required: The layer that set the final order.
    - `reason` 'rule_matched' | 'rule_default_selection' | 'rule_output_partially_eligible' | 'priority_logic' | 'priority_logic_downtime' | 'merchant_preference' | 'experiment_rule' | 'success_rate_ranked' | 'success_rate_downtime' | 'success_rate_exploration' | 'decider_default' | 'preferred_connector' | 'cost_optimized' | 'volume_commitment' | 'debit_network_optimized' | 'no_rule_matched' | 'no_active_rule' | 'rule_output_not_eligible' | 'rule_input_invalid' | 'success_rate_unavailable' | 'no_eligible_connectors' | 'no_active_rule_no_candidates', required
    - `message` string, required: For people reading logs. Not stable; branch on `reason`.
  - `rule` DecideRuleSection, required
    - `status` 'matched' | 'default_selection' | 'no_active_rule', required
    - `output` object, required: The algorithm's output by `type` (`straight_through`, `priority`, `volume_split`, `volume_split_priority`), laid out as in `RoutingEvaluateResponse.output` with connectors in the `DecideResultConnector` shape.
    - `selected` DecideResultConnector[], required: The connectors the rule layer chose, narrowed to the eligible ones.
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
    - `eligible` DecideResultConnector[], required: The connectors the payment method can use.
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
  - `success_rate` DecideSuccessRateSection, required
    - `status` 'applied' | 'failed', required
    - `approach` string, nullable, required: The decider's routing approach, for example `SR_SELECTION_V3_ROUTING`.
    - `scores` DecideConnectorScore[], required: Every scored connector, best first.
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
      - `score` number, required
    - `scheduled_outage` boolean, nullable, required
    - `diagnostics` object, nullable, required: The decider's internals, for support: `head_before_downtime_check`, `reset_approach`, `dimension {value, level}`, `filter_wise_gateways`, `priority_logic {tag, output}`, `dynamic_mga_enabled`, `gateway_mga_id_map`, `rust_based_decider` and `latency_ms`. Not covered by compatibility guarantees.
  - `cost` DecideCostSection, required
    - `outcome` 'COST_WON' | 'AUTH_WON', required
    - `reason` string, required
    - `cost_saved_bps` number, nullable, required
    - `qualified_count` integer, required
    - `margin` number, required
    - `ev_gap_top2` number, nullable, required
    - `ranked` DecideRankedConnector[], required: Every connector ranked on expected value, best first.
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
      - `auth_rate` number, required
      - `cost_bps` number, nullable, required
      - `cost_source` 'IN_HOUSE' | 'SEED' | 'HYPERSENSE', nullable, required
      - `cost_model` object, nullable, required: `brand`, `variant`, `issuer`, `ccy`, `ic_category`, `pct_bps`, `fixed_fee`.
      - `ev` number, required
      - `is_sr_head` boolean, required
      - `is_chosen` boolean, required
  - `volume_steering` DecideVolumeSteeringSection, required
    - `outcome` 'STEERED' | 'SR_PREVAILED', required
    - `reason` string, required
    - `sr_head` DecideResultConnector, required
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
    - `chosen` DecideResultConnector, required
      - `gateway_name` string, required
      - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
    - `sr_gap_conceded` number, nullable, required
    - `steer_rate` number, nullable, required
    - `steering_count` integer, required
    - `run_id` string, nullable, required
    - `blocked` object[], required
      - `connector` DecideResultConnector, required
        - `gateway_name` string, required
        - `payment_merchant_connector_id` string, nullable, required: Null for a connector named without an account.
      - `gate` string, required
  - `debit_routing` DebitRoutingOutput, required
    - `co_badged_card_networks_info` object[]
      - `network` string
      - `saving_percentage` number
    - `issuer_country` string
    - `is_regulated` boolean
    - `regulated_name` string, nullable
    - `card_type` string
  - `warnings` DecideWarning[], required: Problems the decision routed around. Routing problems never fail the call.
    - `code` 'rule_input_invalid' | 'rule_evaluation_failed' | 'rule_output_not_eligible' | 'rule_output_partially_eligible' | 'success_rate_failed', required
    - `param` string, nullable, required: The request field the warning is about, such as `card.card_network`, when there is one.
    - `message` string, required

## Other responses

- `400`: Missing required fields, unknown fields, incorrect JSON types, invalid routing input or an existing hybrid evaluation error.
- `401`: Authentication required.
- `403`: The authenticated session or API key cannot act on this merchant.
- `500`: Routing configuration or service unavailable.

## Changes

- **2026-11-03** `718ef5ac8634`: 2 breaking, 17 info
  - removed the required property `decision` from the response with the `200` status
  - removed the required property `evaluated_connectors` from the response with the `200` status
  - added the new optional request property `payment_type`
  - the request property `routing_config/eligible_connectors/items/payment_merchant_connector_id` became nullable
  - …15 more
- **2026-10-29** `491a815aaa59`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/juspay/apis/decision-engine/changes/decide/post.md)

---

[API](https://skmtc.dev/juspay/apis/decision-engine.md) - [All operations](https://skmtc.dev/juspay/apis/decision-engine/llms.txt) - [OpenAPI document](https://skmtc.dev/juspay/apis/decision-engine/revisions/718ef5ac8634?raw)
