---
title: "Create a new rule"
method: POST
path: "/rules"
tags: ["Rules"]
---

# Create a new rule

`POST /rules`

## Request

- Base URL: `https://api.synci.io/api/v1`
- URL: `https://api.synci.io/api/v1/rules`
- Auth: one of:
  - OAuth 2
    - Authorization code: `https://api.synci.io/oauth/authorize`
    - Token URL: `https://api.synci.io/oauth/token`
  - HTTP bearer

Rules automatically categorize or transform transactions. A rule attached to a financial account runs on
new transactions as they are fetched from the bank and its changes are permanent; a rule attached to a
transfer link runs on transactions as they are transferred and only changes the destination copy.

A rule has **conditions** and **actions**. Conditions decide whether the rule applies; a rule with no
conditions always applies. Actions run when it does, and every rule needs at least one. Each action that
runs is recorded as a rule log.

Action values accept [Liquid templates](https://shopify.github.io/liquid/). Reference transaction fields
with `{{ transaction.field_name }}` and transform them with filters:

| Filter | Example | Description |
|--------|---------|-------------|
| `remove` | `{{ transaction.creditor.name \| remove: "PREFIX " }}` | Remove a substring |
| `upcase` / `downcase` | `{{ transaction.creditor.name \| upcase }}` | Change case |
| `regex_capture` | `{{ transaction.creditor.name \| regex_capture: '/^(\w+)/' }}` | Extract a regex capture group |
| `date_add` | `{{ transaction.booking_date \| date_add: 7 }}` | Add or subtract days from a date |
| `remove_at` | `{{ transaction.memo \| remove_at: 1, 5 }}` | Remove characters at positions |
| `keep_at` | `{{ transaction.memo \| keep_at: 6 }}` | Keep only characters from a position |

The standard Liquid filters (`replace`, `truncate`, `split`, `append`, `prepend`, and so on) are available
too. Values without `{{` or `{%` are literal.

Account rules (`BANK` scope) attach to bank accounts only; attaching one to a crypto or brokerage account
returns `422`. Use a transfer link rule for those. How many conditions, actions and attached rules a plan
allows is listed on the [pricing page](https://synci.io/pricing).

## Request body

- CreateRuleRequest
  - `name` string, required: The name of the rule.
  - `description` string, nullable: An optional description of what the rule does.
  - `enabled` boolean: Whether the rule is active. Disabled rules are not applied.
  - `trigger_on_any_condition` boolean: When enabled, only one condition must match for the rule to be applied.
  - `skip_other_rules_when_triggered` boolean: If the rule's conditions are met, stop processing other rules attached to the same financial account or transfer link.
  - `scope` 'BANK' | 'TRANSFER': Where a rule runs. `BANK` rules are applied to transactions as they are stored in Synci (changes are permanent) and attach to financial accounts or institutions. `TRANSFER` rules are applied while transactions are transferred to a destination (changes land only in the destination copy) and attach to transfer links. Which destinations a transfer rule fits is derived from its actions, not declared up front.
  - `type` 'BANK' | 'YNAB_TRANSFER_LINK' | 'LUNCH_MONEY_TRANSFER_LINK' | 'GOOGLE_SHEETS_TRANSFER_LINK' | 'NOTION_TRANSFER_LINK': The legacy rule type. `BANK` rules are applied to transactions as they are fetched from the bank and can only be attached to financial accounts. The transfer link types are applied while transactions are transferred to the destination and can only be attached to transfer links. | | |---| | `BANK` <br/> Applied to bank transactions as they are fetched. Attaches to financial accounts. | | `YNAB_TRANSFER_LINK` <br/> Applied while transferring transactions to a YNAB budget account. | | `LUNCH_MONEY_TRANSFER_LINK` <br/> Applied while transferring transactions to a Lunch Money account. | | `GOOGLE_SHEETS_TRANSFER_LINK` <br/> Applied while transferring transactions to a Google Sheet. | | `NOTION_TRANSFER_LINK` <br/> Applied while transferring transactions to a Notion database. |
  - `conditions` object[]: The conditions that must be met for the rule to be applied. If no conditions are provided, the rule's actions will always be executed.
    - `field_name` string, required
    - `operator` 'EQUALS' | 'DOES_NOT_EQUAL' | 'CONTAINS' | 'DOES_NOT_CONTAIN' | 'STARTS_WITH' | 'DOES_NOT_START_WITH' | 'ENDS_WITH' | 'DOES_NOT_END_WITH' | 'GREATER_THAN' | 'GREATER_THAN_OR_EQUAL' | 'LESS_THAN' | 'LESS_THAN_OR_EQUAL' | 'MATCHES_REGEX', required: The comparison operator a rule condition uses to compare a transaction field against the condition's value.
    - `value` string, nullable
    - `transaction_type` 'BANK' | 'YNAB'
  - `actions` object[]: The actions to execute when the rule's conditions are met. Every rule must have at least one action.
    - `order` integer, nullable
    - `action_type` 'SET_DESTINATION_FIELD' | 'SET_OUTPUT_FIELD' | 'SET_YNAB_FIELD' | 'SET_LUNCH_MONEY_FIELD' | 'SET_FIELD' | 'CHANGE_YNAB_FIELD' | 'APPLY_REGEX' | 'STOP_TRANSFER', required: The kind of change a rule action performs when the rule's conditions are met. | | |---| | `SET_DESTINATION_FIELD` <br/> Set a destination transaction field, resolved against the attached transfer link's destination. Only available for transfer rules. | | `SET_OUTPUT_FIELD` <br/> Set a canonical transaction field on the outgoing copy, read by canonical-output channels (spreadsheet destinations today). Only available for transfer rules. | | `SET_YNAB_FIELD` <br/> Set a field on the YNAB transaction. Legacy alias of SET_DESTINATION_FIELD with a YNAB field. | | `SET_LUNCH_MONEY_FIELD` <br/> Set a field on the Lunch Money transaction. Legacy alias of SET_DESTINATION_FIELD with a Lunch Money field. | | `SET_FIELD` <br/> Set a field on the transaction. | | `CHANGE_YNAB_FIELD` <br/> | | `APPLY_REGEX` <br/> | | `STOP_TRANSFER` <br/> Prevent the transaction from being transferred to the destination. Only available for transfer link rules. |
    - `field_name` string, nullable
    - `value` string, nullable
  - `financial_accounts` object[]: The financial accounts to attach the rule to, each with an `id` and an `order`. Only allowed for `BANK` rules.
    - `id` integer
    - `order` integer
  - `transfer_links` object[]: The transfer links to attach the rule to, each with an `id` and an `order`. Only allowed for transfer link rule types.
    - `id` integer
    - `order` integer
  - `institutions` string[]: Reserved for Synci administrators.
  - `banks` object[]
    - `id` integer: Reserved for Synci administrators.
    - `order` integer

## Response `200`

- object
  - `message` 'Rule created.', required
  - `data` RuleResource, required
    - `id` string, required
    - `scope` string, required: Where the rule runs: - `BANK`: applied to transactions as they are stored in Synci (changes are permanent). Attaches to financial accounts. - `TRANSFER`: applied while transactions are transferred to a destination (changes land only in the destination copy). Attaches to transfer links.
    - `compatible_destinations` string[]: The destinations this transfer rule can attach to, derived from its actions. Included when the rule's actions are loaded; always empty for `BANK`-scope rules.
    - `output_compatible` string: Whether this transfer rule can attach to a bank account as an output rule, shaping the account's transactions on third-party API pulls, SimpleFIN syncs, and webhook payloads. True when every action speaks the canonical transaction vocabulary. Included when the rule's actions are loaded; always false for `BANK`-scope rules.
    - `type` string, required: The legacy rule type. Deprecated: use `scope` and `compatible_destinations` instead. May be null for rules created with `scope`.
    - `name` string, required
    - `description` string, required
    - `enabled` string, required: Whether the rule is active. Disabled rules are not applied.
    - `migrated` string, required: Whether the rule was migrated from the old version of Synci. Does not count against your quota.
    - `trigger_on_any_condition` string, required: When enabled, only one condition must match for the rule to be applied.
    - `skip_other_rules_when_triggered` string, required: If the rule's conditions are met, stop processing other rules attached to the same financial account or transfer link.
    - `conditions` RuleConditionResource[]: Conditions are the criteria that must be met for a rule to be applied.
      - `id` string, required
      - `transaction_type` string, required: The type of transaction the condition is evaluated against.
      - `field_name` string, required: The name of the transaction field the condition checks.
      - `operator` string, required: The comparison operator used to evaluate the condition.
      - `value` string, required: The value the transaction field is compared against.
      - `rules` RuleResource[]: The rules the condition belongs to.
      - `rules_count` string
      - `created_at` string, required
      - `updated_at` string, required
    - `conditions_count` string
    - `actions` RuleActionResource[]: Actions are the instructions that are executed when a rule's conditions are met. Each action includes an `order` value — actions are executed in ascending order.
      - `id` string, required
      - `order` string, required: The position of the action in the rule's action list. Actions are executed in ascending order.
      - `action_type` string, required: The kind of change the action performs.
      - `field_name` string, required: The name of the field the action sets.
      - `value` string, required: The value to set. Supports plain strings or Liquid templates for dynamic expressions.
      - `rules` RuleResource[]: The rules the action belongs to.
      - `rules_count` string
      - `created_at` string, required
      - `updated_at` string, required
    - `actions_count` string
    - `financial_accounts` object[]: Financial accounts that the rule is attached to. Each object includes: - rule_position: The order of the rule in the financial account's rule list. Rules are applied in ascending order. - financial_account: The financial account resource data
      - `rule_position` integer, required
      - `financial_account` FinancialAccountResource, required
        - `id` string, required
        - `financial_connection_id` string
        - `financial_connection` FinancialConnectionResource
          - `id` string, required
          - `institution_id` string, required
          - `region` string, required: Residency region of the connection's data (`eu`, `us`), decided by the institution's provider when the connection was created.
          - `institution` InstitutionResource
            - `id` string, required
            - `integrator` string, required: The integrator used to connect to this institution.
            - `region` string, required: Residency region connections to this institution are stored in (`eu`, `us`).
            - `country` string, required: ISO 3166-1 alpha-2 country code.
            - `name` string, required: Name of the institution.
            - `bic` string, required: Institution Identifier Code (BIC/SWIFT code).
            - `external_id` string, required: The ID of the institution as provided by the integrator.
            - `logo` string, required: URL to the institution's logo, as provided by the integrator.
            - `supported` string, required: Whether the institution is supported. Will be true in most cases, but might be false if the integrator stops supporting an institution.
            - `supports_pending_transactions` string, required: Whether the institution supports pending transactions.
            - `supports_card_accounts` string, required: Whether the institution supports card accounts.
            - `max_historical_days` string, required: The maximum number of days of historical data this institution can provide. `null` where the provider imposes no such limit and fetches whatever the bank holds, which is the case for every US institution. Do not read null as zero.
            - `max_access_valid_for_days` string, required: Also known as consent lifetime. The maximum number of days access to this institution may be valid for. For most European institutions this ranges from 90 to 180 days. `null` where access does not expire on a schedule and no periodic re-consent is required, which is the case for every US institution: those connections break only when the bank breaks them.
            - `supported_products` string, required: The kinds of data this institution can serve, e.g. `["ACCOUNTS", "TRANSACTIONS", "INVESTMENTS"]`. `null` means the provider does not report it, NOT that the institution serves nothing: treat it as no information rather than as a negative. Only US institutions report it today.
            - `category` string, nullable, required: The category of the financial institution.
            - `updated_at` string, required: The date and time when the institution was last updated.
          - `enabled` string, required
          - `health` HealthResource
            - `status` string, required: Health status: HEALTHY (last request succeeded), FAILING (recent requests failed), or DEAD (10 or more consecutive failures).
            - `integrator_message` string, required: The most recent error message reported by the provider, if any.
            - `failure_count` string, required: The number of consecutive failed requests.
            - `transient_message` string, required: A provider-side outage currently blocking part of the sync (for example the institution being down for maintenance). Not counted as a failure: the status stays HEALTHY while Synci retries automatically. Null when nothing is being retried.
            - `transient_failure_count` string, required: The number of consecutive sync attempts refused by that outage.
            - `last_attempt_at` string, required: When the last sync attempt occurred.
          - `status` string, nullable, required: Provider-neutral lifecycle status (PENDING_AUTHORIZATION / CONNECTED / ...).
          - `status_message` string, required: Provider status message.
          - `sync_balances` string, required: Whether balances should be synced. Applies to all accounts belonging to this connection.
          - `supports_reauthorization` boolean, required: Whether `PUT /reauthorize` will start a fresh OAuth flow against this connection's provider. True for every currently supported provider (GoCardless renews PSD2 consent; Akahu and SnapTrade re-grant a previously-disabled connection). When false, the reauthorize endpoint responds with `REAUTHORIZATION_NOT_SUPPORTED`.
          - `supports_manage` boolean, required: Whether GET /manage will return a URL you can redirect the user to so they can manage their existing connections directly with the provider. Currently true for Akahu (sends them to oauth.akahu.nz where they can add / revoke banks under their enduring consent), false for GoCardless and SnapTrade.
          - `max_historical_days` string, nullable, required: The maximum number of days of historical data Synci is able to fetch. Applies to all accounts belonging to this connection.
          - `access_valid_for_days` string, nullable, required: Also known as consent lifetime. The number of days Synci is able to access accounts belonging to this connection. E.g. if this is set to 180 days, you will have to re-authenticate the connection every 180 days. Synci will send you an email when the expiry date is approaching.
          - `consent_expires_at` string, nullable, required: The date and time when the bank consent expires and the connection has to be reauthorized, or null for providers that grant enduring consent (Akahu, SnapTrade).
          - `reference` string, required: Caller-supplied correlation id set at creation (e.g. a platform developer's own end-user id). Filterable via ?filter[reference]=.
          - `accounts_last_synced_at` string, required
          - `setup_pending` boolean, required: Whether the post-connection setup (choosing accounts, naming them, picking a sync start date) is still to be finished. While true the accounts exist but their first transaction sync is held back until `POST /setup/complete`, or until the setup goes stale. Always false for connections created by API clients.
          - `setup_renewal` boolean, required: True while a pending setup belongs to a consent renewal rather than a new connection: only the account choice is asked for, and the accounts the user had enabled stay pre-selected.
          - `activated_at` string, required: When the connection first went live (provider callback succeeded). Null while consent is still pending or the flow was abandoned.
          - `financial_accounts` FinancialAccountResource[]: Financial accounts belonging to this connection.
          - `financial_accounts_count` string
          - `created_at` string, required
          - `updated_at` string, required
        - `config` InstitutionConfigResource
          - `map_fields` object, required: Which field(s) are used when mapping the "payee", "description" and "date" fields for a transaction. One of the fixed option names (`AUTO`, `NONE`, `CREDITOR_NAME`, `BOOKING_DATE`, ...). Version 2 of the API stores an ordered fallback chain per field instead; this is the closest fixed option for the stored chain, and a chain without an equivalent reads as `AUTO`.
            - `payee` string, required
            - `description` string, required
            - `date` string, required
          - `enrichment` object, required: Enrich transaction data with additional information from an external provider
            - `enabled` string, required: Whether transaction enrichment is enabled
            - `provider` string, required: The provider to use for transaction enrichment.
            - `country` string, required: The country where transactions are made. Providing a country significantly improves enrichment accuracy.
          - `sync_start_date` string, nullable, required: The date to start syncing transactions from. Cannot be earlier than the date the connection was authorized minus the connection's `max_historical_days`. Will default to today if not set.
          - `sync_auto` string, required: Whether data should be synced automatically. If set to false, you will need to manually trigger a sync every time you want to refresh data.
          - `sync_pending_transactions` string, required: Whether pending transactions should be synced. For some banks, setting this to true can cause duplicate transactions.
          - `pending_settlement_matching` string, required: Whether a booked transaction can settle an existing pending transaction when the amount changed. Card pre-authorizations (fuel stations, hotels, car rentals) are often authorized with a placeholder amount that changes when the transaction is booked, together with the transaction's identifiers. When enabled, a booked transaction that matches a pending transaction's counterparty (and card details, when the bank provides them) within `pending_settlement_max_days` days updates that pending transaction instead of creating a duplicate. Only pending transactions are matched this way; deduplication of booked transactions is unaffected. Enabled by default; `null` means the default applies.
          - `pending_settlement_max_days` string, required: The maximum number of days between a pending transaction and its booked settlement for `pending_settlement_matching` to link the two. Defaults to 7; `null` means the default applies.
          - `fuzzy_counterparty_matching` string, required: Whether a counterparty name the bank re-words when a transaction settles can still match the pending entry it replaces ("NORWEGIAN.COM" settling as "NORWEGIAN.C 3284405123"). Descriptors that conflict rather than truncate or extend never match, and only pending transactions are matched this way. Enabled by default; `null` means the default applies.
          - `fuzzy_counterparty_min_chars` string, required: The minimum number of characters two re-worded counterparty descriptors must align on for `fuzzy_counterparty_matching` to treat them as the same party. Defaults to 6; `null` means the default applies.
          - `sync_balances` string, required: Whether balances should be synced.
          - `sync_frequency_in_minutes` string, required: How often to sync data, in minutes. The permitted minimum is set by the subscriber's plan (`max_sync_frequency_minutes` in the plan's features, see `GET /billing/plans`); 30 is only the absolute lower bound any plan could set. This is the CONFIGURED value. The interval actually used may be longer if the institution has refused requests on its own daily cap, in which case the account is demoted to a slower cadence automatically.
          - `fields_for_duplicate_filtering` string[], nullable: An array of Transaction fields to use when filtering duplicate transactions. When a new transaction is synced, these fields are compared with existing transactions. If the fields are identical, the new transaction is considered a duplicate and will be ignored. This should only be used if you are struggling with duplicate transactions, and know which fields can be used to filter them. For everyone else, omit this field.
        - `health` HealthResource
          - `status` string, required: Health status: HEALTHY (last request succeeded), FAILING (recent requests failed), or DEAD (10 or more consecutive failures).
          - `integrator_message` string, required: The most recent error message reported by the provider, if any.
          - `failure_count` string, required: The number of consecutive failed requests.
          - `transient_message` string, required: A provider-side outage currently blocking part of the sync (for example the institution being down for maintenance). Not counted as a failure: the status stays HEALTHY while Synci retries automatically. Null when nothing is being retried.
          - `transient_failure_count` string, required: The number of consecutive sync attempts refused by that outage.
          - `last_attempt_at` string, required: When the last sync attempt occurred.
        - `enabled` string, required
        - `live` string, required: Whether the account is in use: it AND its connection are enabled. A disabled connection keeps each account's own `enabled` as the user set it, but none of its accounts sync until it is enabled again.
        - `integrator` string, required: Provider that populates this account (GOCARDLESS / AKAHU / SNAPTRADE).
        - `account_category` string, nullable, required: High-level kind of account: BANK (checking/savings, provided by banking providers), INVESTMENT (brokerage), DEPOSIT (cash sub-account at a broker), LOC (line of credit), LOAN (a manual loan Synci models from its terms). Determines which fields are populated on the account.
        - `loan` unknown[], nullable: The loan terms, rate history and derived figures. Present on LOAN accounts only.
          - unknown
        - `raw_type` string, required: Provider's free-form sub-type label (SnapTrade only). Examples: "Roth IRA", "TFSA", "Cash". Null for bank accounts.
        - `cash_balance` object, nullable, required: Uninvested cash held at the broker, for INVESTMENT accounts. Null for bank accounts.
          - `amount` string, required
          - `currency` string, required
        - `total_balance` object, nullable, required: Broker-reported total account value (positions + cash) for INVESTMENT accounts. Brokerages report this on the account payload rather than as a dated snapshot, so it does not appear in the balances endpoint. Null for bank accounts.
          - `amount` string, required
          - `currency` string, required
        - `meta` string, required: Provider-specific extras that don't fit anywhere else (e.g. SnapTrade's `meta.type`/`meta.status` for crypto exchanges). Treat as opaque — schema is provider-defined.
        - `account_number_masked` string: Masked account number (e.g. "****1234"). Only present when the provider supplies it (SnapTrade brokerages, and banks that report a masked card PAN via GoCardless); null otherwise.
        - `name` string, required: Name of the account, as assigned by the financial institution.
        - `custom_name` string, required: Custom name for the account, as defined by the end user.
        - `institution_name` string, required: The lender's name on a manual account, as the user entered it. Null on provider accounts and on manual accounts without one: group those under their connection's institution ("Manual accounts").
        - `display_name` string, required: Name of the account as defined by the end user within online channels.
        - `bban` string: Basic Bank Account Number (BBAN).
        - `scan` string: UK SortCodeAccountNumber (6 digit sort code + 8 digit account number), reported by some UK banks.
        - `iban` string: International Bank Account Number (IBAN).
        - `bic` string: Bank Identifier Code (BIC/SWIFT) associated with the account.
        - `owner_name` string: Name of the legal account owner. If there is more than one owner, then e.g. two names might be noted here. For a corporate account, the corporate name is used for this attribute.
        - `owner_address` string: Address of the legal account owner, when reported by the institution.
        - `currency` string, required: ISO 4217 currency code.
        - `product_name` string, required: Product Name of the Institution for this account, proprietary definition.
        - `cash_account_type` string, required: ExternalCashAccountType1Code from ISO 20022 (e.g. CACC, CARD, SVGS), when reported by the institution.
        - `account_usage` string, required: Usage of the account: PRIV (private personal account) or ORGA (professional account).
        - `linked_accounts` string: Name of a cash account associated to pending card transactions, when the institution reports one. Banks often put that account's number here, so it is omitted with the other identifiers.
        - `details` string, required: Specifications that might be provided by the financial institution - characteristics of the account - characteristics of the relevant card.
        - `msisdn` string: An alias to a payment account via a registered mobile phone number.
        - `integrator_id` string: The financial account ID provided by the integrator.
        - `institution_id` string: The financial account ID provided by the institution/bank.
        - `details_last_synced_at` string, required: Last time the financial account details were fetched from the integrator.
        - `transactions_last_synced_at` string, required: Last time the financial account transactions were fetched from the integrator.
        - `transactions_backfill_cursor` string, nullable, required: History is fetched newest-first in windows of up to 90 days. While older windows are still being fetched this is the earliest date already covered; transactions before it arrive on subsequent syncs, at the pace the institution's daily request allowance permits. Null once the account's full history (up to the connection's `max_historical_days`) is in.
        - `balances_last_synced_at` string, required: Last time the financial account balances were fetched from the integrator.
        - `balance` object, required: Balance of the account at the last sync. To get all types of balances at different dates, use the balances endpoints.
          - `available` union
            - string
            - 0
          - `cleared` union
            - string
            - 0
          - `currency` string, required: ISO 4217 currency of these figures. Only differs from the account's `currency` on a multi-currency account (`XXX`), which holds a balance per currency: this is the one shown.
        - `rules` object[]: The rules attached to this financial account
          - `order` integer, required
          - `rule` object, required
        - `transfer_links` TransferLinkResource[]: Left out for tokens without the `transfer-links:read` scope.
          - `id` string, required
          - `financial_account_id` string, required: The ID of the financial account transactions are being transferred from.
          - `financial_account` FinancialAccountResource (recursive)
          - `destination_type` string, required: The type of destination the transfer link sends transactions to: - **YNAB**: a YNAB budget account. - **LUNCH_MONEY**: a Lunch Money account. - **GOOGLE_SHEETS**: a Google Sheet. - **NOTION**: a Notion database.
          - `destination_id` string, required: The ID of the destination transactions are being transferred to. The type of resource the ID refers to depends on the destination type: - **YNAB**: the ID of a YNAB budget account. - **LUNCH_MONEY**: the ID of a Lunch Money account. - **GOOGLE_SHEETS**: the ID of a Google Sheet. - **NOTION**: the ID of a Notion database.
          - `destination` union: The associated destination resource. Will be included in the response if the `include` query parameter contains `destination`.
            - YnabBudgetAccountResource
              - …
            - LunchMoneyAccountResource
              - …
            - GoogleSheetResource
              - …
            - NotionDatabaseResource
              - …
          - `transfer_start_date` string, required: The date from which the transfer link will start transferring transactions. If not provided, all available transactions in the attached financial account will be transferred regardless of their date.
          - `active` string, required: Whether the transfer link is enabled.
          - `sync_mode` string, required: Which streams to push to the destination: - `transactions`: only individual transactions (default for bank sources) - `balance`: only periodic balance snapshots - `transactions_and_balance`: both (default for brokerage / crypto sources)
          - `on_booked_change` object, required: Which destination fields to update when a transaction's booked status changes. If not provided, all fields will be updated.
            - `update_status` string, required
            - `update_payee` string, required
            - `update_description` string, required
            - `update_amount` string, required
          - `rules` object[]: The rules attached to the transfer link. Will be included in the response if the `include` query parameter contains `rules`. Each object includes: - order: The position of the rule in the transfer link's rule list. Rules are applied in ascending order. - rule: The rule resource data
            - `order` integer, required
            - `rule` object, required
          - `created_at` string, required
          - `updated_at` string, required
        - `transfer_links_count` string: Left out for tokens without the `transfer-links:read` scope.
        - `created_at` string, required
        - `updated_at` string, required
    - `financial_accounts_count` string
    - `transfer_links` object[]: Transfer links that the rule is attached to. Left out for tokens without the `transfer-links:read` scope. Each object includes: - rule_position: The order of the rule in the transfer link's rule list. Rules are applied in ascending order. - transfer_link: The transfer link resource data
      - `rule_position` integer, required
      - `transfer_link` TransferLinkResource, required
        - `id` string, required
        - `financial_account_id` string, required: The ID of the financial account transactions are being transferred from.
        - `financial_account` FinancialAccountResource
          - `id` string, required
          - `financial_connection_id` string
          - `financial_connection` FinancialConnectionResource
            - `id` string, required
            - `institution_id` string, required
            - `region` string, required: Residency region of the connection's data (`eu`, `us`), decided by the institution's provider when the connection was created.
            - `institution` InstitutionResource
              - …
            - `enabled` string, required
            - `health` HealthResource
              - …
            - `status` string, nullable, required: Provider-neutral lifecycle status (PENDING_AUTHORIZATION / CONNECTED / ...).
            - `status_message` string, required: Provider status message.
            - `sync_balances` string, required: Whether balances should be synced. Applies to all accounts belonging to this connection.
            - `supports_reauthorization` boolean, required: Whether `PUT /reauthorize` will start a fresh OAuth flow against this connection's provider. True for every currently supported provider (GoCardless renews PSD2 consent; Akahu and SnapTrade re-grant a previously-disabled connection). When false, the reauthorize endpoint responds with `REAUTHORIZATION_NOT_SUPPORTED`.
            - `supports_manage` boolean, required: Whether GET /manage will return a URL you can redirect the user to so they can manage their existing connections directly with the provider. Currently true for Akahu (sends them to oauth.akahu.nz where they can add / revoke banks under their enduring consent), false for GoCardless and SnapTrade.
            - `max_historical_days` string, nullable, required: The maximum number of days of historical data Synci is able to fetch. Applies to all accounts belonging to this connection.
            - `access_valid_for_days` string, nullable, required: Also known as consent lifetime. The number of days Synci is able to access accounts belonging to this connection. E.g. if this is set to 180 days, you will have to re-authenticate the connection every 180 days. Synci will send you an email when the expiry date is approaching.
            - `consent_expires_at` string, nullable, required: The date and time when the bank consent expires and the connection has to be reauthorized, or null for providers that grant enduring consent (Akahu, SnapTrade).
            - `reference` string, required: Caller-supplied correlation id set at creation (e.g. a platform developer's own end-user id). Filterable via ?filter[reference]=.
            - `accounts_last_synced_at` string, required
            - `setup_pending` boolean, required: Whether the post-connection setup (choosing accounts, naming them, picking a sync start date) is still to be finished. While true the accounts exist but their first transaction sync is held back until `POST /setup/complete`, or until the setup goes stale. Always false for connections created by API clients.
            - `setup_renewal` boolean, required: True while a pending setup belongs to a consent renewal rather than a new connection: only the account choice is asked for, and the accounts the user had enabled stay pre-selected.
            - `activated_at` string, required: When the connection first went live (provider callback succeeded). Null while consent is still pending or the flow was abandoned.
            - `financial_accounts` FinancialAccountResource[]: Financial accounts belonging to this connection.
            - `financial_accounts_count` string
            - `created_at` string, required
            - `updated_at` string, required
          - `config` InstitutionConfigResource
            - `map_fields` object, required: Which field(s) are used when mapping the "payee", "description" and "date" fields for a transaction. One of the fixed option names (`AUTO`, `NONE`, `CREDITOR_NAME`, `BOOKING_DATE`, ...). Version 2 of the API stores an ordered fallback chain per field instead; this is the closest fixed option for the stored chain, and a chain without an equivalent reads as `AUTO`.
              - …
            - `enrichment` object, required: Enrich transaction data with additional information from an external provider
              - …
            - `sync_start_date` string, nullable, required: The date to start syncing transactions from. Cannot be earlier than the date the connection was authorized minus the connection's `max_historical_days`. Will default to today if not set.
            - `sync_auto` string, required: Whether data should be synced automatically. If set to false, you will need to manually trigger a sync every time you want to refresh data.
            - `sync_pending_transactions` string, required: Whether pending transactions should be synced. For some banks, setting this to true can cause duplicate transactions.
            - `pending_settlement_matching` string, required: Whether a booked transaction can settle an existing pending transaction when the amount changed. Card pre-authorizations (fuel stations, hotels, car rentals) are often authorized with a placeholder amount that changes when the transaction is booked, together with the transaction's identifiers. When enabled, a booked transaction that matches a pending transaction's counterparty (and card details, when the bank provides them) within `pending_settlement_max_days` days updates that pending transaction instead of creating a duplicate. Only pending transactions are matched this way; deduplication of booked transactions is unaffected. Enabled by default; `null` means the default applies.
            - `pending_settlement_max_days` string, required: The maximum number of days between a pending transaction and its booked settlement for `pending_settlement_matching` to link the two. Defaults to 7; `null` means the default applies.
            - `fuzzy_counterparty_matching` string, required: Whether a counterparty name the bank re-words when a transaction settles can still match the pending entry it replaces ("NORWEGIAN.COM" settling as "NORWEGIAN.C 3284405123"). Descriptors that conflict rather than truncate or extend never match, and only pending transactions are matched this way. Enabled by default; `null` means the default applies.
            - `fuzzy_counterparty_min_chars` string, required: The minimum number of characters two re-worded counterparty descriptors must align on for `fuzzy_counterparty_matching` to treat them as the same party. Defaults to 6; `null` means the default applies.
            - `sync_balances` string, required: Whether balances should be synced.
            - `sync_frequency_in_minutes` string, required: How often to sync data, in minutes. The permitted minimum is set by the subscriber's plan (`max_sync_frequency_minutes` in the plan's features, see `GET /billing/plans`); 30 is only the absolute lower bound any plan could set. This is the CONFIGURED value. The interval actually used may be longer if the institution has refused requests on its own daily cap, in which case the account is demoted to a slower cadence automatically.
            - `fields_for_duplicate_filtering` string[], nullable: An array of Transaction fields to use when filtering duplicate transactions. When a new transaction is synced, these fields are compared with existing transactions. If the fields are identical, the new transaction is considered a duplicate and will be ignored. This should only be used if you are struggling with duplicate transactions, and know which fields can be used to filter them. For everyone else, omit this field.
          - `health` HealthResource
            - `status` string, required: Health status: HEALTHY (last request succeeded), FAILING (recent requests failed), or DEAD (10 or more consecutive failures).
            - `integrator_message` string, required: The most recent error message reported by the provider, if any.
            - `failure_count` string, required: The number of consecutive failed requests.
            - `transient_message` string, required: A provider-side outage currently blocking part of the sync (for example the institution being down for maintenance). Not counted as a failure: the status stays HEALTHY while Synci retries automatically. Null when nothing is being retried.
            - `transient_failure_count` string, required: The number of consecutive sync attempts refused by that outage.
            - `last_attempt_at` string, required: When the last sync attempt occurred.
          - `enabled` string, required
          - `live` string, required: Whether the account is in use: it AND its connection are enabled. A disabled connection keeps each account's own `enabled` as the user set it, but none of its accounts sync until it is enabled again.
          - `integrator` string, required: Provider that populates this account (GOCARDLESS / AKAHU / SNAPTRADE).
          - `account_category` string, nullable, required: High-level kind of account: BANK (checking/savings, provided by banking providers), INVESTMENT (brokerage), DEPOSIT (cash sub-account at a broker), LOC (line of credit), LOAN (a manual loan Synci models from its terms). Determines which fields are populated on the account.
          - `loan` unknown[], nullable: The loan terms, rate history and derived figures. Present on LOAN accounts only.
            - unknown
          - `raw_type` string, required: Provider's free-form sub-type label (SnapTrade only). Examples: "Roth IRA", "TFSA", "Cash". Null for bank accounts.
          - `cash_balance` object, nullable, required: Uninvested cash held at the broker, for INVESTMENT accounts. Null for bank accounts.
            - `amount` string, required
            - `currency` string, required
          - `total_balance` object, nullable, required: Broker-reported total account value (positions + cash) for INVESTMENT accounts. Brokerages report this on the account payload rather than as a dated snapshot, so it does not appear in the balances endpoint. Null for bank accounts.
            - `amount` string, required
            - `currency` string, required
          - `meta` string, required: Provider-specific extras that don't fit anywhere else (e.g. SnapTrade's `meta.type`/`meta.status` for crypto exchanges). Treat as opaque — schema is provider-defined.
          - `account_number_masked` string: Masked account number (e.g. "****1234"). Only present when the provider supplies it (SnapTrade brokerages, and banks that report a masked card PAN via GoCardless); null otherwise.
          - `name` string, required: Name of the account, as assigned by the financial institution.
          - `custom_name` string, required: Custom name for the account, as defined by the end user.
          - `institution_name` string, required: The lender's name on a manual account, as the user entered it. Null on provider accounts and on manual accounts without one: group those under their connection's institution ("Manual accounts").
          - `display_name` string, required: Name of the account as defined by the end user within online channels.
          - `bban` string: Basic Bank Account Number (BBAN).
          - `scan` string: UK SortCodeAccountNumber (6 digit sort code + 8 digit account number), reported by some UK banks.
          - `iban` string: International Bank Account Number (IBAN).
          - `bic` string: Bank Identifier Code (BIC/SWIFT) associated with the account.
          - `owner_name` string: Name of the legal account owner. If there is more than one owner, then e.g. two names might be noted here. For a corporate account, the corporate name is used for this attribute.
          - `owner_address` string: Address of the legal account owner, when reported by the institution.
          - `currency` string, required: ISO 4217 currency code.
          - `product_name` string, required: Product Name of the Institution for this account, proprietary definition.
          - `cash_account_type` string, required: ExternalCashAccountType1Code from ISO 20022 (e.g. CACC, CARD, SVGS), when reported by the institution.
          - `account_usage` string, required: Usage of the account: PRIV (private personal account) or ORGA (professional account).
          - `linked_accounts` string: Name of a cash account associated to pending card transactions, when the institution reports one. Banks often put that account's number here, so it is omitted with the other identifiers.
          - `details` string, required: Specifications that might be provided by the financial institution - characteristics of the account - characteristics of the relevant card.
          - `msisdn` string: An alias to a payment account via a registered mobile phone number.
          - `integrator_id` string: The financial account ID provided by the integrator.
          - `institution_id` string: The financial account ID provided by the institution/bank.
          - `details_last_synced_at` string, required: Last time the financial account details were fetched from the integrator.
          - `transactions_last_synced_at` string, required: Last time the financial account transactions were fetched from the integrator.
          - `transactions_backfill_cursor` string, nullable, required: History is fetched newest-first in windows of up to 90 days. While older windows are still being fetched this is the earliest date already covered; transactions before it arrive on subsequent syncs, at the pace the institution's daily request allowance permits. Null once the account's full history (up to the connection's `max_historical_days`) is in.
          - `balances_last_synced_at` string, required: Last time the financial account balances were fetched from the integrator.
          - `balance` object, required: Balance of the account at the last sync. To get all types of balances at different dates, use the balances endpoints.
            - `available` union
              - …
            - `cleared` union
              - …
            - `currency` string, required: ISO 4217 currency of these figures. Only differs from the account's `currency` on a multi-currency account (`XXX`), which holds a balance per currency: this is the one shown.
          - `rules` object[]: The rules attached to this financial account
            - `order` integer, required
            - `rule` object, required
          - `transfer_links` TransferLinkResource[]: Left out for tokens without the `transfer-links:read` scope.
          - `transfer_links_count` string: Left out for tokens without the `transfer-links:read` scope.
          - `created_at` string, required
          - `updated_at` string, required
        - `destination_type` string, required: The type of destination the transfer link sends transactions to: - **YNAB**: a YNAB budget account. - **LUNCH_MONEY**: a Lunch Money account. - **GOOGLE_SHEETS**: a Google Sheet. - **NOTION**: a Notion database.
        - `destination_id` string, required: The ID of the destination transactions are being transferred to. The type of resource the ID refers to depends on the destination type: - **YNAB**: the ID of a YNAB budget account. - **LUNCH_MONEY**: the ID of a Lunch Money account. - **GOOGLE_SHEETS**: the ID of a Google Sheet. - **NOTION**: the ID of a Notion database.
        - `destination` union: The associated destination resource. Will be included in the response if the `include` query parameter contains `destination`.
          - YnabBudgetAccountResource
            - `id` string, required
            - `budget_id` string, required
            - `budget` YnabBudgetResource
              - …
            - `ynab_id` string, required: The account's ID in YNAB.
            - `health` HealthResource
              - …
            - `name` string, required
            - `type` string, required
            - `on_budget` string, required: Whether the account is on budget in YNAB.
            - `closed` string, required: Whether the account is closed in YNAB.
            - `note` string, required: The account note from YNAB, if set.
            - `balance` string, required: The account balance as reported by YNAB.
            - `cleared_balance` string, required: The cleared balance as reported by YNAB.
            - `uncleared_balance` string, required: The uncleared balance as reported by YNAB.
            - `transfer_payee_id` string, required: The YNAB payee ID used for transfers to this account.
            - `direct_import_linked` string, required: Whether the account is linked to YNAB Direct Import.
            - `last_reconciled_at` string, required: When the account was last reconciled in YNAB.
            - `transfer_links` TransferLinkResource[]: Left out for tokens without the `transfer-links:read` scope.
            - `created_at` string, required
            - `updated_at` string, required
          - LunchMoneyAccountResource
            - `id` string, required
            - `connection_id` string, required
            - `connection` LunchMoneyConnectionResource
              - …
            - `health` HealthResource
              - …
            - `lunch_money_id` string, required: The account's ID in Lunch Money.
            - `name` string, required
            - `display_name` string, required: The account's display name in Lunch Money, if set.
            - `type` string, required: The account type as reported by Lunch Money, e.g. "cash" or "credit".
            - `subtype` string, required: The account subtype as reported by Lunch Money, if set.
            - `currency` string, required
            - `balance` string, required: The account balance as reported by Lunch Money.
            - `balance_as_of` string, required: When the balance was last updated in Lunch Money.
            - `closed_on` string, required: When the account was closed in Lunch Money, if closed.
            - `exclude_from_transactions` string, required: Whether the account is excluded from transactions in Lunch Money.
            - `transfer_links` TransferLinkResource[]: Left out for tokens without the `transfer-links:read` scope.
            - `created_at` string, required
            - `updated_at` string, required
          - GoogleSheetResource
            - `id` string, required
            - `connection_id` string, required
            - `connection` GoogleSheetsConnectionResource
              - …
            - `health` HealthResource
              - …
            - `name` string, required: Display name of the spreadsheet in Synci.
            - `spreadsheet_id` string, required: The spreadsheet's ID in Google Sheets, as found in its URL.
            - `spreadsheet_name` string, required: The spreadsheet's title in Google Sheets.
            - `spreadsheet_url` string, required: Link to open the spreadsheet in Google Sheets.
            - `is_synci_managed` string, required: True when the spreadsheet was created by Synci; false when an existing spreadsheet was attached.
            - `transactions_sheet_gid` string, required: The gid of the tab that receives transactions, if assigned.
            - `transactions_sheet_name` string, required: The name of the tab that receives transactions, if assigned.
            - `live_balance_sheet_gid` string, required: The gid of the tab that holds current balances, if assigned.
            - `live_balance_sheet_name` string, required: The name of the tab that holds current balances, if assigned.
            - `balance_history_sheet_gid` string, required: The gid of the tab that records balance history, if assigned.
            - `balance_history_sheet_name` string, required: The name of the tab that records balance history, if assigned.
            - `transfer_links` TransferLinkResource[]: Left out for tokens without the `transfer-links:read` scope.
            - `last_synced_at` string, required: When data was last synced to the spreadsheet.
            - `created_at` string, required
            - `updated_at` string, required
          - NotionDatabaseResource
            - `id` string, required
            - `connection_id` string, required
            - `connection` NotionConnectionResource
              - …
            - `health` HealthResource
              - …
            - `name` string, required: Display name of the database in Synci.
            - `title` string, required: The database's title in Notion.
            - `database_id` string, required: The Notion database ID.
            - `data_source_id` string, required: The Notion data source (table) transactions are written to.
            - `database_url` string, required: Link to open the database in Notion.
            - `parent_page_id` string, required: The Notion page the database lives under, when known, and its title (a dashboard's `name` falls back to this).
            - `parent_page_title` string, required
            - `is_synci_managed` string, required: True when the database was created by Synci; false when an existing database was attached.
            - `layout` string, required: "dashboard" when the Synci Finance template was adopted (transactions relate to Accounts, Categories and Months); "flat" for plain databases.
            - `header_config` string, required: Ordered list of transaction field keys written as database properties.
            - `property_map` string, required: Field key to Notion property id map Synci writes through.
            - `accounts_database_id` string, required: The supporting databases next to this one, when present.
            - `categories_database_id` string, required
            - `months_database_id` string, required
            - `balance_history_database_id` string, required
            - `balance_available` string, required: Whether balance databases exist or can be provisioned (requires a parent page).
            - `transfer_links` TransferLinkResource[]: Left out for tokens without the `transfer-links:read` scope.
            - `last_synced_at` string, required: When data was last synced to the database.
            - `created_at` string, required
            - `updated_at` string, required
        - `transfer_start_date` string, required: The date from which the transfer link will start transferring transactions. If not provided, all available transactions in the attached financial account will be transferred regardless of their date.
        - `active` string, required: Whether the transfer link is enabled.
        - `sync_mode` string, required: Which streams to push to the destination: - `transactions`: only individual transactions (default for bank sources) - `balance`: only periodic balance snapshots - `transactions_and_balance`: both (default for brokerage / crypto sources)
        - `on_booked_change` object, required: Which destination fields to update when a transaction's booked status changes. If not provided, all fields will be updated.
          - `update_status` string, required
          - `update_payee` string, required
          - `update_description` string, required
          - `update_amount` string, required
        - `rules` object[]: The rules attached to the transfer link. Will be included in the response if the `include` query parameter contains `rules`. Each object includes: - order: The position of the rule in the transfer link's rule list. Rules are applied in ascending order. - rule: The rule resource data
          - `order` integer, required
          - `rule` object, required
        - `created_at` string, required
        - `updated_at` string, required
    - `transfer_links_count` string: Left out for tokens without the `transfer-links:read` scope.
    - `created_at` string, required
    - `updated_at` string, required

## Other responses

- `401`: Unauthenticated
- `403`: Authorization error
- `422`: Validation error

## Changes

- **2026-10-29** `77c60670768e`: 1 breaking, 22 info
  - the `data` response's property type changed from no type to `object` for status `200`
  - added the optional property `data/actions` to the response with the `200` status
  - added the optional property `data/actions_count` to the response with the `200` status
  - added the optional property `data/compatible_destinations` to the response with the `200` status
  - …19 more
- **2026-10-27** `dc2173489128`: 2 info
  - added the optional property `data/allOf[subschema #1: RuleResource]/financial_accounts/items/financial_account/loan` to the response with the `200` status
  - added the required property `data/allOf[subschema #1: RuleResource]/financial_accounts/items/financial_account/institution_name` to the response with the `200` status
- **2026-10-25** `bd0918c24b26`: 1 breaking, 1 info
  - the response property `data/allOf[subschema #1: RuleResource]/financial_accounts/items/financial_account/config/sync_start_date` became nullable for the status `200`
  - added the required property `data/allOf[subschema #1: RuleResource]/financial_accounts/items/financial_account/live` to the response with the `200` status

[Operation history](https://skmtc.dev/synci/apis/synci/changes/rules/post.md)

---

[API](https://skmtc.dev/synci/apis/synci.md) - [All operations](https://skmtc.dev/synci/apis/synci/llms.txt) - [OpenAPI document](https://skmtc.dev/synci/apis/synci/revisions/77f5bd15f77e?raw)
