---
title: "Create a categorization rule"
method: POST
path: "/books/rules"
tags: ["Books"]
---

# Create a categorization rule

`POST /books/rules`

## Request

- Base URL: `https://api.mercury.com/api/v1`
- URL: `https://api.mercury.com/api/v1/books/rules`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/mercurytechnologies/apis/mercury-api/docs/books/rules/post.ts> (a function with typed inputs; its response is checked against the schema)

Creates a categorization rule in a Books instance: a rule that automatically categorizes imported transactions to a ledger, i.e. a general ledger (GL) account. The rule only applies to transactions categorized from now on; it does not re-categorize existing transactions. The body has `conditions` (1 to 10, all of which must match; logical AND, there is no OR) and `outputs` (at most one of each kind, so today exactly one `setLedger`), in the same shape getBooksCategorizationRules returns, so a listed rule's `conditions` and `outputs` can be sent back as is. Each condition has a `tag` and `contents`: `amount` (`operator`, one of `lessThan`, `lessThanOrEqualTo`, `greaterThan`, `greaterThanOrEqualTo`, or `equalTo`, and `amount`, a signed threshold in dollars: money in is positive and money out negative), `description` (`contains`), `counterparty` (`name`), `debitCard` (`debitCardId`), `creditCard` (`creditCardId`), `user` (`userId`), or `customCategory` (`customCategoryId`); every card, user, and custom category must belong to the organization. The only output is `setLedger` (`ledgerId`), a ledger the caller may edit (not read-only) in the Books instance; to find ledger IDs, use getBooksLedgers. There is no priority field: the new rule is placed among the existing rules by how specific its conditions are, and the first matching rule applies. Returns the created `rule`, in the shape getBooksCategorizationRules returns. A rule that doesn't validate, a ledger without a GL account, or conditions the organization already has a rule for are a 400 and create nothing; to see existing rules, use getBooksCategorizationRules.

## Query parameters

- `booksId` string, uuid: The Books instance to act on. Required for agent organization tokens; defaults to the token organization's instance.

## Request body

- CreateBooksAPICategorizationRuleRequest: A categorization rule to create. There is no priority field: Books places the new rule among the existing ones by how specific its conditions are.
  - `conditions` BooksAPICategorizationRuleCondition[], required: The conditions a transaction must match, from 1 to 10. Every condition must match (logical AND); there is no OR, so an "any of" rule is written as separate rules. The organization may not already have a rule with the same conditions.
    - union: A condition a transaction must match for a categorization rule to apply. `tag` says which condition it is (`amount`, `description`, `counterparty`, `debitCard`, `creditCard`, `user`, or `customCategory`) and `contents` holds its fields. A rule's conditions must all match; there is no OR, so an "any of" rule is written as separate rules.
      - object
        - `contents` BooksAPICategorizationRuleAmountCondition, required: Matches transactions whose amount compares to a threshold (`tag`: `amount`). The amount is signed: money in (credits) is positive and money out (debits) is negative, and the threshold is compared against it as is, so `lessThan` `-50` matches outflows of more than $50. A range is two amount conditions on the same rule.
          - `amount` number, double, required: The threshold, in dollars. Signed like the transaction amount: positive for money in, negative for money out.
          - `operator` 'lessThan' | 'lessThanOrEqualTo' | 'greaterThan' | 'greaterThanOrEqualTo' | 'equalTo', required: How to compare the transaction amount to `amount`.
        - `tag` 'amount', required
      - object
        - `contents` BooksAPICategorizationRuleDescriptionCondition, required: Matches transactions whose raw bank description contains a text, ignoring case (`tag`: `description`).
          - `contains` string, required: The text the bank description must contain, ignoring case.
        - `tag` 'description', required
      - object
        - `contents` BooksAPICategorizationRuleCounterpartyCondition, required: Matches transactions whose counterparty name is exactly a name (`tag`: `counterparty`). Only Mercury transactions carry a counterparty.
          - `name` string, required: The counterparty name the transaction must have, matched exactly.
        - `tag` 'counterparty', required
      - object
        - `contents` BooksAPICategorizationRuleDebitCardCondition, required: Matches transactions made with a Mercury debit card (`tag`: `debitCard`).
          - `debitCardId` string, uuid, required: The ID of the debit card.
        - `tag` 'debitCard', required
      - object
        - `contents` BooksAPICategorizationRuleCreditCardCondition, required: Matches transactions made with a Mercury credit card (`tag`: `creditCard`).
          - `creditCardId` string, uuid, required: The ID of the credit card.
        - `tag` 'creditCard', required
      - object
        - `contents` BooksAPICategorizationRuleUserCondition, required: Matches transactions made by a team member (`tag`: `user`).
          - `userId` string, uuid, required: The ID of the user who made the transaction.
        - `tag` 'user', required
      - object
        - `contents` BooksAPICategorizationRuleCustomCategoryCondition, required: Matches transactions whose current Mercury custom (expense) category is a category (`tag`: `customCategory`).
          - `customCategoryId` string, uuid, required: The ID of the custom category.
        - `tag` 'customCategory', required
  - `outputs` BooksAPICategorizationRuleOutput[], required: What the rule applies to a matching transaction: at most one output of each kind, so today exactly one `setLedger`. Its ledger must be one the caller may edit in this Books instance.
    - `contents` BooksAPICategorizationRuleSetLedgerOutput, required: Sets the transaction's categorization to a ledger, i.e. a general ledger (GL) account (`tag`: `setLedger`).
      - `ledgerId` string, base58 (max length 22), required: The ID of the ledger matching transactions are categorized to.
    - `tag` 'setLedger', required

## Response `200`

- CreateBooksAPICategorizationRuleResponse: The created categorization rule.
  - `rule` object, required: The created rule, as the list endpoint returns it.
    - `conditions` BooksAPICategorizationRuleCondition[], required: The conditions a transaction must match. At least one; every condition must match (logical AND). There is no OR: an "any of" rule is written as separate rules.
      - union: A condition a transaction must match for a categorization rule to apply. `tag` says which condition it is (`amount`, `description`, `counterparty`, `debitCard`, `creditCard`, `user`, or `customCategory`) and `contents` holds its fields. A rule's conditions must all match; there is no OR, so an "any of" rule is written as separate rules.
        - object
          - `contents` BooksAPICategorizationRuleAmountCondition, required: Matches transactions whose amount compares to a threshold (`tag`: `amount`). The amount is signed: money in (credits) is positive and money out (debits) is negative, and the threshold is compared against it as is, so `lessThan` `-50` matches outflows of more than $50. A range is two amount conditions on the same rule.
            - `amount` number, double, required: The threshold, in dollars. Signed like the transaction amount: positive for money in, negative for money out.
            - `operator` 'lessThan' | 'lessThanOrEqualTo' | 'greaterThan' | 'greaterThanOrEqualTo' | 'equalTo', required: How to compare the transaction amount to `amount`.
          - `tag` 'amount', required
        - object
          - `contents` BooksAPICategorizationRuleDescriptionCondition, required: Matches transactions whose raw bank description contains a text, ignoring case (`tag`: `description`).
            - `contains` string, required: The text the bank description must contain, ignoring case.
          - `tag` 'description', required
        - object
          - `contents` BooksAPICategorizationRuleCounterpartyCondition, required: Matches transactions whose counterparty name is exactly a name (`tag`: `counterparty`). Only Mercury transactions carry a counterparty.
            - `name` string, required: The counterparty name the transaction must have, matched exactly.
          - `tag` 'counterparty', required
        - object
          - `contents` BooksAPICategorizationRuleDebitCardCondition, required: Matches transactions made with a Mercury debit card (`tag`: `debitCard`).
            - `debitCardId` string, uuid, required: The ID of the debit card.
          - `tag` 'debitCard', required
        - object
          - `contents` BooksAPICategorizationRuleCreditCardCondition, required: Matches transactions made with a Mercury credit card (`tag`: `creditCard`).
            - `creditCardId` string, uuid, required: The ID of the credit card.
          - `tag` 'creditCard', required
        - object
          - `contents` BooksAPICategorizationRuleUserCondition, required: Matches transactions made by a team member (`tag`: `user`).
            - `userId` string, uuid, required: The ID of the user who made the transaction.
          - `tag` 'user', required
        - object
          - `contents` BooksAPICategorizationRuleCustomCategoryCondition, required: Matches transactions whose current Mercury custom (expense) category is a category (`tag`: `customCategory`).
            - `customCategoryId` string, uuid, required: The ID of the custom category.
          - `tag` 'customCategory', required
    - `glCodeName` string, nullable: The display name of the general ledger (GL) account the rule categorizes to. Absent when the rule sets none.
    - `id` string, uuid, required: The rule's stable identifier.
    - `lastApplied` string, yyyy-mm-ddThh:MM:ssZ, nullable: The last time the rule matched a transaction. Absent if it never has.
    - `outputs` BooksAPICategorizationRuleOutput[], required: What the rule applies to a matching transaction. At least one.
      - `contents` BooksAPICategorizationRuleSetLedgerOutput, required: Sets the transaction's categorization to a ledger, i.e. a general ledger (GL) account (`tag`: `setLedger`).
        - `ledgerId` string, base58 (max length 22), required: The ID of the ledger matching transactions are categorized to.
      - `tag` 'setLedger', required
    - `status` 'active' | 'inactive' | 'invalid', required: Whether the rule currently categorizes transactions.

## Other responses

- `400`: Invalid `body` or `booksId`

## Changes

- **2026-11-03** `95c77a617769`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/mercurytechnologies/apis/mercury-api/changes/books/rules/post.md)

---

[API](https://skmtc.dev/mercurytechnologies/apis/mercury-api.md) - [All operations](https://skmtc.dev/mercurytechnologies/apis/mercury-api/llms.txt) - [OpenAPI document](https://skmtc.dev/mercurytechnologies/apis/mercury-api/revisions/95c77a617769?raw)
