---
title: "Evaluate a planned ACH transaction"
method: POST
path: "/processor/signal/evaluate"
tags: ["plaid"]
---

# Evaluate a planned ACH transaction

`POST /processor/signal/evaluate`

Use `/processor/signal/evaluate` to evaluate a planned ACH transaction as a processor to get a return risk assessment (such as a risk score and risk tier) and additional risk signals.

In order to obtain a valid score for an ACH transaction, Plaid must have an access token for the account, and the Item must be healthy (receiving product updates) or have recently been in a healthy state. If the transaction does not meet eligibility requirements, an error will be returned corresponding to the underlying cause. If `/processor/signal/evaluate` is called on the same transaction multiple times within a 24-hour period, cached results may be returned. For more information please refer to our error documentation on [item errors](/docs/errors/item/) and [Link in Update Mode](/docs/link/update-mode/).

Note: This request may take some time to complete if Signal is being added to an existing Item. This is because Plaid must communicate directly with the institution when retrieving the data for the first time. To reduce this latency, you can call `/signal/prepare` on the Item before you need to request Signal data.

## Request body

- ProcessorSignalEvaluateRequest — ProcessorSignalEvaluateRequest defines the request schema for `/processor/signal/evaluate`
  - `client_id` string — Your Plaid API `client_id`. The `client_id` is required and may be provided either in the `PLAID-CLIENT-ID` header or as part of a request body.
  - `secret` string — Your Plaid API `secret`. The `secret` is required and may be provided either in the `PLAID-SECRET` header or as part of a request body.
  - `processor_token` string, required — The processor token obtained from the Plaid integration partner. Processor tokens are in the format: `processor-<environment>-<identifier>`
  - `client_transaction_id` string, required — The unique ID that you would like to use to refer to this transaction. For your convenience mapping your internal data, you could use your internal ID/identifier for this transaction. The max length for this field is 36 characters.
  - `amount` number, double, required — The transaction amount, in USD (e.g. `102.05`)
  - `user_present` boolean, nullable — `true` if the end user is present while initiating the ACH transfer and the endpoint is being called; `false` otherwise (for example, when the ACH transfer is scheduled and the end user is not present, or you call this endpoint after the ACH transfer but before submitting the Nacha file for ACH processing).
  - `client_user_id` string — A unique ID that identifies the end user in your system. This ID is used to correlate requests by a user with multiple Items. Personally identifiable information, such as an email address or phone number, should not be used in the `client_user_id`.
  - `is_recurring` boolean, nullable — **true** if the ACH transaction is a recurring transaction; **false** otherwise
  - `default_payment_method` string, nullable — The default ACH or non-ACH payment method to complete the transaction. `SAME_DAY_ACH`: Same Day ACH by NACHA. The debit transaction is processed and settled on the same day `NEXT_DAY_ACH`: Next Day ACH settlement for debit transactions, offered by some payment processors `STANDARD_ACH`: standard ACH by NACHA `REAL_TIME_PAYMENTS`: real-time payments such as RTP and FedNow `DEBIT_CARD`: if the default payment is over debit card networks `MULTIPLE_PAYMENT_METHODS`: if there is no default debit rail or there are multiple payment methods Possible values: `SAME_DAY_ACH`, `NEXT_DAY_ACH`, `STANDARD_ACH`, `REAL_TIME_PAYMENTS`, `DEBIT_CARD`, `MULTIPLE_PAYMENT_METHODS`
  - `user` SignalUser — Details about the end user initiating the transaction (i.e., the account holder). When calling `/signal/evaluate` or `/signal/processor/evaluate`, this field is optional, but strongly recommended to increase the accuracy of Signal results.
    - `name` SignalPersonName, nullable — The user's legal name
      - `prefix` string, nullable — The user's name prefix (e.g. "Mr.")
      - `given_name` string, nullable — The user's given name. If the user has a one-word name, it should be provided in this field.
      - `middle_name` string, nullable — The user's middle name
      - `family_name` string, nullable — The user's family name / surname
      - `suffix` string, nullable — The user's name suffix (e.g. "II")
    - `phone_number` string, nullable — The user's phone number, in E.164 format: +{countrycode}{number}. For example: "+14151234567"
    - `email_address` string, nullable — The user's email address.
    - `address` SignalAddressData, nullable — Data about the components comprising an address.
      - `city` string — The full city name
      - `region` string, nullable — The region or state Example: `"NC"`
      - `street` string — The full street address Example: `"564 Main Street, APT 15"`
      - `postal_code` string, nullable — The postal code
      - `country` string, nullable — The ISO 3166-1 alpha-2 country code
  - `device` SignalDevice — Details about the end user's device. When calling `/signal/evaluate` or `/signal/processor/evaluate`, this field is optional, but strongly recommended to increase the accuracy of Signal results.
    - `ip_address` string, nullable — The IP address of the device that initiated the transaction
    - `user_agent` string, nullable — The user agent of the device that initiated the transaction (e.g. "Mozilla/5.0")
  - `ruleset_key` string, nullable — The key of the Ruleset to use for this transaction. You can configure a Ruleset using the Signal dashboard located within the Plaid Dashboard. If not provided, no Ruleset will be used. This feature is currently in closed beta; to request access, contact your account manager.

## Response `200`

OK

- ProcessorSignalEvaluateResponse — ProcessorSignalEvaluateResponse defines the response schema for `/processor/signal/evaluate`
  - `request_id` string, required — A unique identifier for the request, which can be used for troubleshooting. This identifier, like all Plaid identifiers, is case sensitive.
  - `scores` SignalScores, nullable, required — Risk scoring details broken down by risk category.
    - `customer_initiated_return_risk` CustomerInitiatedReturnRisk — The object contains a risk score and a risk tier that evaluate the transaction return risk of an unauthorized debit. Common return codes in this category include: "R05", "R07", "R10", "R11", "R29". These returns typically have a return time frame of up to 60 calendar days. During this period, the customer of financial institutions can dispute a transaction as unauthorized.
      - `score` integer, required — A score from 1-99 that indicates the transaction return risk: a higher risk score suggests a higher return likelihood.
      - `risk_tier` integer, required — DEPRECATED. Use Signal Rules instead to transform the `score` into a useful action. A tier corresponding to the projected likelihood that the transaction, if initiated, will be subject to a return. In the `customer_initiated_return_risk` object, there are five risk tiers corresponding to the scores: 1: Predicted customer-initiated return incidence rate between 0.00% - 0.02% 2: Predicted customer-initiated return incidence rate between 0.02% - 0.05% 3: Predicted customer-initiated return incidence rate between 0.05% - 0.1% 4: Predicted customer-initiated return incidence rate between 0.1% - 0.5% 5: Predicted customer-initiated return incidence rate greater than 0.5%
    - `bank_initiated_return_risk` BankInitiatedReturnRisk — The object contains a risk score and a risk tier that evaluate the transaction return risk because an account is overdrawn or because an ineligible account is used. Common return codes in this category include: "R01", "R02", "R03", "R04", "R06", "R08", "R09", "R13", "R16", "R17", "R20", "R23". These returns have a turnaround time of 2 banking days.
      - `score` integer, required — A score from 1-99 that indicates the transaction return risk: a higher risk score suggests a higher return likelihood.
      - `risk_tier` integer, required — DEPRECATED. Use Signal Rules instead to transform the `score` into a useful action. In the `bank_initiated_return_risk` object, there are eight risk tiers corresponding to the scores: 1: Predicted bank-initiated return incidence rate between 0.0% - 0.5% 2: Predicted bank-initiated return incidence rate between 0.5% - 1.5% 3: Predicted bank-initiated return incidence rate between 1.5% - 3% 4: Predicted bank-initiated return incidence rate between 3% - 5% 5: Predicted bank-initiated return incidence rate between 5% - 10% 6: Predicted bank-initiated return incidence rate between 10% - 15% 7: Predicted bank-initiated return incidence rate between 15% and 50% 8: Predicted bank-initiated return incidence rate greater than 50%
  - `core_attributes` SignalEvaluateCoreAttributes — The core attributes object contains additional data that can be used to assess the ACH return risk. Examples of data include: `days_since_first_plaid_connection`: The number of days since the first time the Item was connected to an application via Plaid `plaid_connections_count_7d`: The number of times the Item has been connected to applications via Plaid over the past 7 days `plaid_connections_count_30d`: The number of times the Item has been connected to applications via Plaid over the past 30 days `total_plaid_connections_count`: The number of times the Item has been connected to applications via Plaid `is_savings_or_money_market_account`: Indicates whether the ACH transaction funding account is a savings/money market account For the full list and detailed documentation of core attributes available, or to request that core attributes not be returned, contact Sales or your Plaid account manager
    - `unauthorized_transactions_count_7d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to unauthorized transactions over the past 7 days from the account that will be debited.
    - `unauthorized_transactions_count_30d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to unauthorized transactions over the past 30 days from the account that will be debited.
    - `unauthorized_transactions_count_60d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to unauthorized transactions over the past 60 days from the account that will be debited.
    - `unauthorized_transactions_count_90d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to unauthorized transactions over the past 90 days from the account that will be debited.
    - `nsf_overdraft_transactions_count_7d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to non-sufficient funds/overdrafts over the past 7 days from the account that will be debited.
    - `nsf_overdraft_transactions_count_30d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to non-sufficient funds/overdrafts over the past 30 days from the account that will be debited.
    - `nsf_overdraft_transactions_count_60d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to non-sufficient funds/overdrafts over the past 60 days from the account that will be debited.
    - `nsf_overdraft_transactions_count_90d` integer, nullable — We parse and analyze historical transaction metadata to identify the number of possible past returns due to non-sufficient funds/overdrafts over the past 90 days from the account that will be debited.
    - `days_since_first_plaid_connection` integer, nullable — The number of days since the first time the Item was connected to an application via Plaid
    - `plaid_connections_count_7d` integer, nullable — The number of times the Item has been connected to applications via Plaid over the past 7 days
    - `plaid_connections_count_30d` integer, nullable — The number of times the Item has been connected to applications via Plaid over the past 30 days
    - `total_plaid_connections_count` integer, nullable — The total number of times the Item has been connected to applications via Plaid
    - `is_savings_or_money_market_account` boolean, nullable — Indicates if the ACH transaction funding account is a savings/money market account
    - `total_credit_transactions_amount_10d` number, double, nullable — The total credit (inflow) transaction amount over the past 10 days from the account that will be debited
    - `total_debit_transactions_amount_10d` number, double, nullable — The total debit (outflow) transaction amount over the past 10 days from the account that will be debited
    - `p50_credit_transactions_amount_28d` number, double, nullable — The 50th percentile of all credit (inflow) transaction amounts over the past 28 days from the account that will be debited
    - `p50_debit_transactions_amount_28d` number, double, nullable — The 50th percentile of all debit (outflow) transaction amounts over the past 28 days from the account that will be debited
    - `p95_credit_transactions_amount_28d` number, double, nullable — The 95th percentile of all credit (inflow) transaction amounts over the past 28 days from the account that will be debited
    - `p95_debit_transactions_amount_28d` number, double, nullable — The 95th percentile of all debit (outflow) transaction amounts over the past 28 days from the account that will be debited
    - `days_with_negative_balance_count_90d` integer, nullable — The number of days within the past 90 days when the account that will be debited had a negative end-of-day available balance
    - `p90_eod_balance_30d` number, double, nullable — The 90th percentile of the end-of-day available balance over the past 30 days of the account that will be debited
    - `p90_eod_balance_60d` number, double, nullable — The 90th percentile of the end-of-day available balance over the past 60 days of the account that will be debited
    - `p90_eod_balance_90d` number, double, nullable — The 90th percentile of the end-of-day available balance over the past 90 days of the account that will be debited
    - `p10_eod_balance_30d` number, double, nullable — The 10th percentile of the end-of-day available balance over the past 30 days of the account that will be debited
    - `p10_eod_balance_60d` number, double, nullable — The 10th percentile of the end-of-day available balance over the past 60 days of the account that will be debited
    - `p10_eod_balance_90d` number, double, nullable — The 10th percentile of the end-of-day available balance over the past 90 days of the account that will be debited
    - `available_balance` number, double, nullable — Available balance, as of the `balance_last_updated` time. The available balance is the current balance less any outstanding holds or debits that have not yet posted to the account.
    - `current_balance` number, double, nullable — Current balance, as of the `balance_last_updated` time. The current balance is the total amount of funds in the account.
    - `balance_last_updated` string, date-time, nullable — Timestamp in [ISO 8601](https://wikipedia.org/wiki/ISO_8601) format (YYYY-MM-DDTHH:mm:ssZ) indicating the last time that the balance for the given account has been updated.
    - `phone_change_count_28d` integer, nullable — The number of times the account's phone numbers on file have changed over the past 28 days
    - `phone_change_count_90d` integer, nullable — The number of times the account's phone numbers on file have changed over the past 90 days
    - `email_change_count_28d` integer, nullable — The number of times the account's email addresses on file have changed over the past 28 days
    - `email_change_count_90d` integer, nullable — The number of times the account's email addresses on file have changed over the past 90 days
    - `address_change_count_28d` integer, nullable — The number of times the account's addresses on file have changed over the past 28 days
    - `address_change_count_90d` integer, nullable — The number of times the account's addresses on file have changed over the past 90 days
    - `plaid_non_oauth_authentication_attempts_count_3d` integer, nullable — The number of non-OAuth authentication attempts via Plaid for this bank account over the past 3 days
    - `plaid_non_oauth_authentication_attempts_count_7d` integer, nullable — The number of non-OAuth authentication attempts via Plaid for this bank account over the past 7 days
    - `plaid_non_oauth_authentication_attempts_count_30d` integer, nullable — The number of non-OAuth authentication attempts via Plaid for this bank account over the past 30 days
    - `failed_plaid_non_oauth_authentication_attempts_count_3d` integer, nullable — The number of failed non-OAuth authentication attempts via Plaid for this bank account over the past 3 days
    - `failed_plaid_non_oauth_authentication_attempts_count_7d` integer, nullable — The number of failed non-OAuth authentication attempts via Plaid for this bank account over the past 7 days
    - `failed_plaid_non_oauth_authentication_attempts_count_30d` integer, nullable — The number of failed non-OAuth authentication attempts via Plaid for this bank account over the past 30 days
    - `debit_transactions_count_10d` integer, nullable — The total number of debit (outflow) transactions over the past 10 days from the account that will be debited
    - `credit_transactions_count_10d` integer, nullable — The total number of credit (inflow) transactions over the past 10 days from the account that will be debited
    - `debit_transactions_count_30d` integer, nullable — The total number of debit (outflow) transactions over the past 30 days from the account that will be debited
    - `credit_transactions_count_30d` integer, nullable — The total number of credit (inflow) transactions over the past 30 days from the account that will be debited
    - `debit_transactions_count_60d` integer, nullable — The total number of debit (outflow) transactions over the past 60 days from the account that will be debited
    - `credit_transactions_count_60d` integer, nullable — The total number of credit (inflow) transactions over the past 60 days from the account that will be debited
    - `debit_transactions_count_90d` integer, nullable — The total number of debit (outflow) transactions over the past 90 days from the account that will be debited
    - `credit_transactions_count_90d` integer, nullable — The total number of credit (inflow) transactions over the past 90 days from the account that will be debited
    - `total_debit_transactions_amount_30d` number, double, nullable — The total debit (outflow) transaction amount over the past 30 days from the account that will be debited
    - `total_credit_transactions_amount_30d` number, double, nullable — The total credit (inflow) transaction amount over the past 30 days from the account that will be debited
    - `total_debit_transactions_amount_60d` number, double, nullable — The total debit (outflow) transaction amount over the past 60 days from the account that will be debited
    - `total_credit_transactions_amount_60d` number, double, nullable — The total credit (inflow) transaction amount over the past 60 days from the account that will be debited
    - `total_debit_transactions_amount_90d` number, double, nullable — The total debit (outflow) transaction amount over the past 90 days from the account that will be debited
    - `total_credit_transactions_amount_90d` number, double, nullable — The total credit (inflow) transaction amount over the past 90 days from the account that will be debited
    - `p50_eod_balance_30d` number, double, nullable — The 50th percentile of the end-of-day available balance over the past 30 days of the account that will be debited
    - `p50_eod_balance_60d` number, double, nullable — The 50th percentile of the end-of-day available balance over the past 60 days of the account that will be debited
    - `p50_eod_balance_90d` number, double, nullable — The 50th percentile of the end-of-day available balance over the past 90 days of the account that will be debited
    - `p50_eod_balance_31d_to_60d` number, double, nullable — The 50th percentile of the end-of-day available balance between day 31 and day 60 over the past 60 days of the account that will be debited
    - `p50_eod_balance_61d_to_90d` number, double, nullable — The 50th percentile of the end-of-day available balance between day 61 and day 90 over the past 60 days of the account that will be debited
    - `p90_eod_balance_31d_to_60d` number, double, nullable — The 90th percentile of the end-of-day available balance between day 31 and day 60 over the past 60 days of the account that will be debited
    - `p90_eod_balance_61d_to_90d` number, double, nullable — The 90th percentile of the end-of-day available balance between day 61 and day 90 over the past 60 days of the account that will be debited
    - `p10_eod_balance_31d_to_60d` number, double, nullable — The 10th percentile of the end-of-day available balance between day 31 and day 60 over the past 60 days of the account that will be debited
    - `p10_eod_balance_61d_to_90d` number, double, nullable — The 10th percentile of the end-of-day available balance between day 61 and day 90 over the past 60 days of the account that will be debited
    - `transactions_last_updated` string, date-time, nullable — Timestamp in [ISO 8601](https://wikipedia.org/wiki/ISO_8601) format (YYYY-MM-DDTHH:mm:ssZ) indicating the last time that the transactions for the given account have been updated.
    - `is_account_closed` boolean, nullable — Indicates if the receiver bank account is closed
    - `is_account_frozen_or_restricted` boolean, nullable — Indicates if the receiver bank account is either frozen or restricted
    - `distinct_ip_addresses_count_3d` integer, nullable — The number of distinct IP addresses linked to the same bank account during Plaid authentication in the last 3 days
    - `distinct_ip_addresses_count_7d` integer, nullable — The number of distinct IP addresses linked to the same bank account during Plaid authentication in the last 7 days
    - `distinct_ip_addresses_count_30d` integer, nullable — The number of distinct IP addresses linked to the same bank account during Plaid authentication in the last 30 days (max 100)
    - `distinct_ip_addresses_count_90d` integer, nullable — The number of distinct IP addresses linked to the same bank account during Plaid authentication in the last 90 days (max 100)
    - `distinct_user_agents_count_3d` integer, nullable — The number of distinct user agents linked to the same bank account during Plaid authentication in the last 3 days
    - `distinct_user_agents_count_7d` integer, nullable — The number of distinct user agents linked to the same bank account during Plaid authentication in the last 7 days
    - `distinct_user_agents_count_30d` integer, nullable — The number of distinct user agents linked to the same bank account during Plaid authentication in the last 30 days
    - `distinct_user_agents_count_90d` integer, nullable — The number of distinct user agents linked to the same bank account during Plaid authentication in the last 90 days
    - `distinct_ssl_tls_connection_sessions_count_3d` integer, nullable — The number of distinct SSL/TLS connection sessions linked to the same bank account during Plaid authentication in the last 3 days
    - `distinct_ssl_tls_connection_sessions_count_7d` integer, nullable — The number of distinct SSL/TLS connection sessions linked to the same bank account during Plaid authentication in the last 7 days
    - `distinct_ssl_tls_connection_sessions_count_30d` integer, nullable — The number of distinct SSL/TLS connection sessions linked to the same bank account during Plaid authentication in the last 30 days
    - `distinct_ssl_tls_connection_sessions_count_90d` integer, nullable — The number of distinct SSL/TLS connection sessions linked to the same bank account during Plaid authentication in the last 90 days
    - `days_since_account_opening` integer, nullable — The number of days since the bank account was opened, as reported by the financial institution
  - `ruleset` Ruleset, nullable — Details about the transaction result after evaluated by the requested Ruleset. If a `ruleset_key` is not provided, this field will be omitted. This feature is currently in closed beta; to request access, contact your account manager.
    - `ruleset_key` string — The key of the Ruleset used for this transaction.
    - `result` 'ACCEPT' | 'REROUTE' | 'REVIEW', required — The result of the rule that was triggered for this transaction. `ACCEPT`: Accept the transaction for processing. `REROUTE`: Reroute the transaction to a different payment method, as this transaction is too risky. `REVIEW`: Review the transaction before proceeding.
    - `triggered_rule_details` RuleDetails, nullable — Rules are run in numerical order. The first rule with a logic match is triggered. These are the details of that rule.
      - `internal_note` string — An optional message attached to the triggered rule, defined within the Dashboard, for your internal use. Useful for debugging, such as “Account appears to be closed.”
      - `custom_action_key` string — A string key, defined within the Dashboard, used to trigger programmatic behavior for a certain result. For instance, you could optionally choose to define a "3-day-hold" `custom_action_key` for an ACCEPT result.
    - `outcome` string — The evaluated outcome for this transaction. This field is deprecated, use `result` or `triggered_rule_details.custom_action_key` instead.
  - `warnings` SignalWarning[] — If bank information was not available to be used in the Signal model, this array contains warnings describing why bank data is missing. If you want to receive an API error instead of Signal scores in the case of missing bank data, file a support ticket or contact your Plaid account manager.
    - `warning_type` string — A broad categorization of the warning. Safe for programmatic use.
    - `warning_code` string — The warning code identifies a specific kind of warning that pertains to the error causing bank data to be missing. Safe for programmatic use. For more details on warning codes, please refer to Plaid standard error codes documentation. If you receive the `ITEM_LOGIN_REQUIRED` warning, we recommend re-authenticating your user by implementing Link's update mode. This will guide your user to fix their credentials, allowing Plaid to start fetching data again for future Signal requests.
    - `warning_message` string — A developer-friendly representation of the warning type. This may change over time and is not safe for programmatic use.

## Other responses

- `default` — Error response.

## Changes

- **2025-05-01** `89dcf373f0a2` — 1 breaking, 1 info
  - removed the required property `ruleset/triggered_rule_details/result` from the response with the `200` status
  - added the required property `ruleset/result` to the response with the `200` status
- **2025-04-21** `3b68659a7975` — 2 info
  - added the optional property `ruleset/triggered_rule_details` to the response with the `200` status
  - response property `ruleset/outcome` deprecated
- **2025-03-26** `09cbc8444913` — 2 warning
  - added the new `CHECK_REPORT_ERROR` enum value to the `error_type` response property for the response status `default`
  - added the new `CONSUMER_REPORT_ERROR` enum value to the `error_type` response property for the response status `default`
- **2024-11-14** `b0263533029b` — 1 breaking
  - the response property `scores` became nullable for the status `200`
- **2024-09-04** `a2c34406c317` — 5 warning, 3 info
  - added the new `PARTNER_ERROR` enum value to the `error_type` response property for the response status `default`
  - added the new `SANDBOX_ERROR` enum value to the `error_type` response property for the response status `default`
  - added the new `TRANSACTIONS_ERROR` enum value to the `error_type` response property for the response status `default`
  - added the new `TRANSACTION_ERROR` enum value to the `error_type` response property for the response status `default`
  - …4 more

[Full history](https://skmtc.dev/plaid/apis/the-plaid-api/changes/processor/signal/evaluate/post.md)

---

[API](https://skmtc.dev/plaid/apis/the-plaid-api.md) · [All operations](https://skmtc.dev/plaid/apis/the-plaid-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/plaid/the-plaid-api/revisions/5eae3158bbfc/schema)
