Categorizing transactions is the process of assigning accounting ledgers to real-world transactions. It is a core accounting process, and ensures that a user’s accounting entries accurately reflect their business.

Teal uses a customizable pipeline to automate categorization, aiming to reduce the need for manual categorization on the part of your users.

Sometimes our pipeline does not have enough information to categorize a transaction. In these cases, the transaction will be categorized into either the Uncategorized Cash Inflow or Uncategorized Cash Outflow ledger.

Configure your platform’s auto-categorizer in the developer portal.

Auto-categorization pipeline

Auto-categorizer pipeline

When a transaction is created, it is sent to the categorization pipeline where categorizers apply different rules to a transaction and try to match it to an instance’s ledgers.

We have four categorizers that run in sequence:

  1. Transfers between accounts
  2. Platform categorization rules
  3. Similar transactions
  4. AI Categorization

If a categorizer selects a ledger, the subsequent categorizers won’t be run. For example, if a transaction is identified as a transfer between accounts, the transaction will not be tested against the platform categorization rules or similar transactions categorizers.



Transfers between accounts

This categorizer recognizes when a transaction is a transfer of funds between two financial accounts.

It looks for a transaction in another ledger that is of an equal and opposite amount, within a 7 day window. If such a transaction exists, it assumes that these are matching transfers and creates two journal entries, one for the inflow and one for the outflow.

This categorizer can only identify matching transactions after both the inflow and outflow exist in the system.

If you or your user know that a cash outflow is a transfer between accounts before the corresponding inflow has been received, you can manually categorize the line entry to the Transfers Between Accounts ledger. This is a special ledger that exists in all chart of accounts templates

The system will then automatically categorize the corresponding inflow when it arrives.


Platform categorization rules

Platforms have the ability to set their own categorization rules. This feature enables you to write expressions, which, when matched, will automatically categorize a transaction into a specific ledger.

This is useful if you are familiar with your customers’ spending and can help reduce the amount of time your customers spend manually categorizing transactions. For example, you might create a platform rule that puts every transaction with the description “UNITED AIRLINES” into a travel expenses ledger.

Categorization rules check transactions using an expression and priority. If a transaction matches multiple rules, the one with higher priority is selected.

Because categorization rules are set at the Platform level these rules will apply to every transaction, regardless of instance, on your platform.

We don’t currently offer Instance level categorization rules. Please reach out to your Teal contact if this is an important feature to you.

See Crafting platform rules below to learn how to write categorization rules in the developer portal.


Similar transactions

This categorizer selects a category based on similar transactions that have previously been categorized by either rules, AI, or the user. For this categorizer to work, each Transaction’s description must be 80% similar and the amount must be within 10%.

Over time, as more transactions are categorized within an instance, this categorizer becomes more effective.


AI Categorization

This categorizer uses an LLM model to select a legder based on the information contained in the Transaction object. It can sometimes take up to 5 minutes for for this categorizer to run.

To prioritize the end-user’s experience, a transaction can be manually categorized before this categorizer finishes running. Manually categorizing the transaction stops the categorizer as posts the transaction.

Uncategorized transactions

Transactions can lack sufficient context and data and cannot be auto-categorized — for example, a bank transaction which is labelled “Payment”.

When a transactions goes through all the categorizers but does not find a match, it is categorized as either Uncategorized Cash Inflow or Uncategorized Cash Outflow. These special ledgers are hardcoded into each chart of accounts template.

In order for books to be balanced, it is necessary to create a user experience to allow users to manually categorize transactions. For steps on how to build an interface like this, see reviewing transactions.


Crafting platform rules

A rule consists of three components:

  • Expression: A conditional statement that is evaluated against each transaction to determine whether it satisfies the criteria of the rule.
  • Priority: If multiple rules match a transaction, the rule with the highest priority will be implemented first.
  • Destination Ledger: This is the name of the ledger into which the transaction will be categorized if the rule conditions are met. If the specified ledger name doesn’t exist in a instance’s chart of accounts, the system will disregard the rule.


Expressions are written by comparing a part of the Transaction object with text, numbers, booleans, or dates.

The Transaction object

The entire Transaction object is accessed via the symbol t and reference specific fields using ., for example, t.description or t.amount.

      "amount": 100,
      "datetime": "2022-01-01T00:00:00Z",
      "description": "Shell Gas Bar 4124",
      "id": "t_9237232",
      "metadata": {
        // ...
      "posted_status": "posted",
      "review_status": "reviewed"

If metadata was added to the Transaction, you can reference it through t.metadata. See submitting transactions for more information on adding metadata to your transactions.

Operators and literals

Expressions may include the following operators and literals:

Regular Expressions

You can use regular expressions in your rule’s expression using the match(pattern, text) function. You can learn more about regular expressions and their syntax here.


Payments to a Specific Vendor

A rule that checks if the transaction description contains “Slack”:

match("Slack", t.description)
Payments to a specific merchant over a given threshold amount

A rule that applies to any transaction where the vendor is “Chevron” and the amount is more than $50:

match("Chevron", t.description) and t.amount > 50
Transactions with Certain Metadata

A rule that looks for transactions with a counterparty attribute in the metadata set to “Sophie’s Contracting LLC”:

t.metadata.counterparty == "Sophie's Contracting LLC"

Further reading & guides