Create a bank rule

Operation ID: createBankRule

Group: Banking › Bank Rules

Open in the interactive reference

POST /banking/bank-rules

Retry-safe: A write that accepts Idempotency-Key: repeating a request with the same key replays the stored answer instead of executing twice.

Creates a bank rule, with its criteria, accounts, and action object. The response contains only its id. Read the record back with GET banking/bank-rules/{id} if you need its stored state; bankRuleNumber comes from a gapless number range and is visible only on that follow-up GET.

A rule is created whole: the header, at least one criterion, the watched bank accounts, and the action object describing the entry to create. createBankEntry and createCreditCardEntry need at least one watched account; createFundTransfer derives its two sides from the action object and takes none.

The watched accounts constrain the action. For createBankEntry and createCreditCardEntry every account must belong to one legal entity (ACCOUNTS_SPAN_ENTITIES), and they must be either all credit card accounts or all not (MIXED_ACCOUNT_TYPES); createCreditCardEntry then works only with credit card accounts and createBankEntry only with the rest, a mismatch being ACTION_ACCOUNT_TYPE_MISMATCH. createFundTransfer is exempt from all three: a transfer spans two accounts, so it may mix entities (intercompany) and account types.

Only three of the four rule actions are implemented. autoMatch is rejected with RULE_ACTION_NOT_SUPPORTED, which is why the input is a three-member union rather than the whole enum.

Operators are constrained by the criterion. Numeric operators apply only to amount, text operators only to description and payeePayor, and an amount value must parse as a number. Anything else is INVALID_CRITERIA with the offending criterion named.

All guards run before the first write, so a rejected request creates nothing.

Parameters

Name In Type Required Description
Api-Version header string · v1 yes The API version this request targets, named by its public identifier. Required on every request; omitting it, or naming a version this company does not have, is answered with 400. This document describes version v1.
Idempotency-Key header string no An opaque caller-chosen string (1-255 characters) that makes this request safe to retry. Repeating the same key with an identical request body replays the original response instead of re-executing - but only once that original request succeeded; a failed attempt re-executes on retry. Repeating the key with a different body is answered with 422. A key still in flight is answered with 409 - as is a key whose original request was interrupted before it finished, for a few minutes afterwards, until that attempt is presumed dead. A completed response stays replayable for 24 hours. The key is scoped to the caller, not to the action: reusing it for a different action is answered with 409 or 422 rather than treated independently. On read actions this header is ignored. On write actions that cannot offer the guarantee it is answered with 400 IDEMPOTENCY_NOT_SUPPORTED rather than silently ignored.

Request body

Required, application/json: createBankRuleInput.

Field Type Required Description
rule string yes The name of the bank rule. Must be unique within the tenant. Example: "Stripe payouts".
action any yes What the rule does when a transaction matches. Only these three are implemented; autoMatch is rejected with RULE_ACTION_NOT_SUPPORTED. One of: "createBankEntry", "createCreditCardEntry", "createFundTransfer". Example: "createBankEntry".
status any yes The status of the rule. Accepted values: 'active' (the rule runs whenever bank rules run), 'inactive' (the rule is kept but does not run). One of: "active", "inactive". Example: "active".
priority number yes The order in which this rule runs relative to other rules. Lower numbers run first. A bank transaction matched by one rule is no longer available to the rules after it. Example: 10.
description string no A description of the rule. Example: "Book Stripe payouts to the clearing account".
bankAccountIds array<string> yes The bank accounts or credit card accounts this rule applies to. At least one is required. They must all belong to the same legal entity, and must be all bank accounts or all credit card accounts, not a mix. See id on GET banking/bank-accounts/:id. Example: ["8f2c1d40-5a6b-4c7d-9e80-1f2a3b4c5d6e"].
criteria array<object> yes The conditions a bank transaction must meet for the rule to act on it. At least one is required. They are evaluated in the order given. Example: [{"criteria":"description","operator":"containsCaseInsensitive","logicalOperator":"and","value":"STRIPE"}].
criteria[].criteria any yes The bank transaction field this criterion tests. Accepted values: 'amount' (the signed transaction amount, negative for money out), 'description' (the description as the bank supplied it), 'payeePayor' (the name of the counterparty). One of: "amount", "description", "payeePayor".
criteria[].operator string yes How the field is compared with value. When criteria is 'amount', use 'equal', 'notEqual', 'greaterThan', 'greaterThanOrEqual', 'lessThan' or 'lessThanOrEqual'. When criteria is 'description' or 'payeePayor', use 'is', 'isNot', 'contains' or 'doesNotContain', which are case-sensitive, or 'isCaseInsensitive', 'isNotCaseInsensitive', 'containsCaseInsensitive' or 'doesNotContainCaseInsensitive'.
criteria[].logicalOperator any no How this criterion combines with the next one. Accepted values: 'and', 'or'. Defaults to 'and'. Ignored on the last criterion. Consecutive criteria joined by the same operator form a group, and groups are always combined with 'and'. For example, A or B, and C matches (A or B) and C, while A and B, or C matches A and B and C. Ignored when criteriaGroups is sent. One of: "and", "or".
criteria[].value string yes The value the field is compared with. Cannot be empty. When criteria is 'amount', send a number, for example '-250.00'. Otherwise, send text.
criteria[].groupKey string no The key of the criteria group this criterion belongs to. See key on criteriaGroups. Required when criteriaGroups is sent, and left out otherwise.
criteriaGroups array<object> no Optional nested AND/OR groups for the criteria. When sent, exactly one group has no parentKey and is the root, every criterion names its group in groupKey, and each group combines its criteria and child groups with its own logicalOperator. For example, (A and B) or C is a root 'or' group holding C and a child 'and' group holding A and B. When left out, criteria are combined using logicalOperator on each criterion.
criteriaGroups[].key string yes A key you choose for the group, unique within this request. Criteria refer to it in groupKey and child groups in parentKey.
criteriaGroups[].parentKey string no The key of the parent group. Left out for the root group.
criteriaGroups[].logicalOperator any yes How the group combines its criteria and child groups. Accepted values: 'and', 'or'. One of: "and", "or".
actionObject object yes The values for the bank entry or credit card entry the rule creates for each bank transaction that meets its criteria. All of its fields are optional. Example: {"accountId":"6d1e4b27-8a90-4c31-b5f2-7e8a9c0d1b23","name":"Stripe payout","description":"Auto-created by rule"}.
actionObject.accountId string no The account each bank entry or credit card entry posts to. It must not be a grouping account. See id on GET accounting/accounts/:id.
actionObject.name string no The name given to each bank entry or credit card entry.
actionObject.description string no The description set on each bank entry or credit card entry and on its line.
actionObject.billableExpense any no Marks the line of each credit card entry as a billable expense when 'yes'. Accepted values: 'yes', 'no'. Applies only to rules with the action 'createCreditCardEntry'. One of: "yes", "no".
actionObject.businessUnitId string no The business unit set on each bank entry or credit card entry.
actionObject.departmentId string no The department set on each bank entry or credit card entry.
actionObject.customerId string no The customer set on each credit card entry. Use only when billableExpense is 'yes'. Not applied to bank entries. See id on GET accounting/customers/:id.
actionObject.vendorId string no A vendor to save on the rule. It is not applied to bank entries or credit card entries. See id on GET accounting/vendors/:id.
actionObject.intercompanyPartnerId string no The intercompany partner set on each bank entry or credit card entry. Applied only when accountId is an elimination account, and ignored otherwise. No endpoint returns intercompany partners.
actionObject.valueAllocationTags array<string> no The value allocation tag codes set on each bank entry or credit card entry. A tag is applied only while value allocation tags are turned on and its dimension is enabled for that type of entry.
actionObject.fromAccountId string no [fk: AccountApi.accounts.id] createFundTransfer only. Source cash account of the transfer, given as its id (a UUID). Required for createFundTransfer.
actionObject.toAccountId string no [fk: AccountApi.accounts.id] createFundTransfer only. Destination cash account of the transfer, given as its id (a UUID). Required for createFundTransfer, and must differ from fromAccountId.
actionObject.fromLineDescription string no createFundTransfer only. Description stamped on the transfer's From line.
actionObject.toLineDescription string no createFundTransfer only. Description stamped on the transfer's To line.
actionObject.intercompanyProcessId string no [fk: IntercompanyProcessApi.intercompanyProcesses.id] createFundTransfer only, given as its id (a UUID). Required when the two accounts belong to different legal entities.
actionObject.transferReason any no createFundTransfer only. Required when the two accounts belong to different legal entities. One of: "funding", "repayment".
actionObject.intercompanyTransactionalCurrency string no createFundTransfer only. Currency the intercompany balance is carried in. Required when the two accounts belong to different legal entities.
actionObject.fromFeeToleranceType any no createFundTransfer only. Whether the sending-side bank fee tolerance is read as a percentage or a fixed amount. One of: "percentage", "fixedAmount".
actionObject.fromFeeToleranceValue decimal no createFundTransfer only. Sending-side tolerance; a shortfall up to this much is booked as a bank fee, beyond it the two transactions are not paired. Left unset, the amounts must match exactly.
actionObject.toFeeToleranceType any no createFundTransfer only. Whether the receiving-side bank fee tolerance is read as a percentage or a fixed amount. One of: "percentage", "fixedAmount".
actionObject.toFeeToleranceValue decimal no createFundTransfer only. Receiving-side tolerance; a shortfall up to this much is booked as a bank fee, beyond it the two transactions are not paired. Left unset, the amounts must match exactly.
{
  "rule": "Stripe payouts",
  "action": "createBankEntry",
  "status": "active",
  "priority": 10,
  "description": "Book Stripe payouts to the clearing account",
  "bankAccountIds": [
    "8f2c1d40-5a6b-4c7d-9e80-1f2a3b4c5d6e"
  ],
  "criteria": [
    {
      "criteria": "description",
      "operator": "containsCaseInsensitive",
      "logicalOperator": "and",
      "value": "STRIPE"
    }
  ],
  "criteriaGroups": [
    {
      "key": "<key>",
      "parentKey": "<parentKey>",
      "logicalOperator": "and"
    }
  ],
  "actionObject": {
    "accountId": "6d1e4b27-8a90-4c31-b5f2-7e8a9c0d1b23",
    "name": "Stripe payout",
    "description": "Auto-created by rule"
  }
}

Response

200 Success

Under data (createBankRuleOutput):

Field Type Required Description
id string yes The unique identifier for the created bank rule. Example: "9f2c6a10-7d34-4c8e-9b21-5a0f3e6d81b7".
{
  "data": {
    "id": "9f2c6a10-7d34-4c8e-9b21-5a0f3e6d81b7"
  },
  "diagnostics": [
    {
      "code": "<code>",
      "message": "<message>",
      "severity": "error",
      "path": [
        "<path>"
      ],
      "details": "<details>"
    }
  ]
}

Response headers

Errors

Code Status
REFERENCE_NOT_FOUND 400
ACCOUNTS_REQUIRED 400
CRITERIA_REQUIRED 400
ACTION_OBJECT_REQUIRED 400
ACCOUNTS_SPAN_ENTITIES 400
MIXED_ACCOUNT_TYPES 400
ACTION_ACCOUNT_TYPE_MISMATCH 400
RULE_ACTION_NOT_SUPPORTED 400
DUPLICATE_RULE_NAME 400
INVALID_FUND_TRANSFER 400
INVALID_CRITERIA 400
ACCOUNT_NOT_POSTABLE 400
IDEMPOTENCY_KEY_CONFLICT 409
IDEMPOTENCY_PAYLOAD_MISMATCH 422

Statuses