---
title: "Create or replace an accounting mapping"
method: PUT
path: "/v2/accounting/mappings"
---

# Create or replace an accounting mapping

`PUT /v2/accounting/mappings`

## Request

- Base URL: `https://api.slash.com`
- URL: `https://api.slash.com/v2/accounting/mappings`
- Auth: API key in header `X-API-Key`

Automatically code one dimension for everything from a source, such as a card or merchant. Replaces any existing mapping for the same source and dimension. Set `applyToExistingEntries` to also recode entries still in review. On platforms that keep account mappings per subsidiary, such as NetSuite, an `account` mapping for an `account` or `accounts_payable` source applies to the connection's default subsidiary; every other mapping applies to the whole connection.

## Request body

- AccountingMappingUpsert: Create or replace the mapping of one source for one dimension. Exactly one of `valueId` (platform and generic dimensions) or `customFieldValue` (custom-field dimensions) is required.
  - `connectionId` string: The connection to write to. Optional when the legal entity has exactly one connection; required when it has several.
  - `source` AccountingMappingSourceInput, required: What a mapping keys on.
    - `type` 'account' | 'virtual_account' | 'card' | 'card_group' | 'merchant' | 'merchant_category' | 'recipient' | 'accounts_payable', required: Which resource `id` names. `account` is an Account (`sa_group_`) and sets the cash-side account of its transactions; `virtual_account` (`subaccount_`), `card` (`c_`), `card_group` (`card_group_`), `merchant` (`merchant_v2_`, from a card transaction's `details.merchant.id`), `merchant_category` (`merchant_category_`, from a card transaction's `details.merchant.categoryId`) and `recipient` (the recipient of a transfer) code the expense side of matching transactions; `accounts_payable` takes no `id` and sets the accounts payable account bills are posted to. When several rules reach the same dimension of one transaction the more specific source wins, from weakest to strongest: `virtual_account`, `card_group`, `card`, `merchant_category`, `merchant`, `recipient`.
    - `id` string: The id of that resource. Required for every type except `accounts_payable`.
  - `dimensionKey` string, required: The dimension to code, a `key` from `GET /v2/accounting/dimensions` that is `enabled` and `mappable` on the connection.
  - `valueId` string: An enabled value of that dimension, from `GET /v2/accounting/dimensions/{dimensionKey}/values`. Not accepted for custom-field dimensions.
  - `customFieldValue` union: The value to set on a `custom_field` dimension, shaped by its `fieldType`: an option value for `select`, a non-empty list of option values for `multiselect`, otherwise a boolean, string or number. Not accepted for other dimensions.
    - string
    - number
    - boolean
    - string[]
  - `applyToExistingEntries` boolean: Also re-code existing entries whose transactions match the source, in the background. Only entries still `in_review` change; anything already synced or ready to sync is left alone. Has no effect on an `accounts_payable` mapping, which is read when a bill syncs. Defaults to `false`, which only affects entries created from now on.

## Response `200`

The mapping as stored.

- AccountingMapping: A rule that codes one dimension automatically: whenever an entry's transaction involves the `source`, the entry gets the mapped value for `dimensionKey`. An `account` source codes the fixed, cash-side line of its transactions; every other source codes the editable lines, and `accounts_payable` sets the account bills are posted to when they sync. Sources are things you can already list through the API (accounts, cards, merchants, recipients, ...); the value is a dimension value id, or for custom-field dimensions the raw field value. One source maps each dimension at most once, so writing the same source and dimension again replaces the earlier mapping.
  - `id` string, required: Mapping id with the `accounting_mapping_` prefix.
  - `connectionId` string, required: The connection the mapping belongs to.
  - `source` AccountingMappingSource, required: What a mapping keys on.
    - `type` 'account' | 'virtual_account' | 'card' | 'card_group' | 'merchant' | 'merchant_category' | 'recipient' | 'accounts_payable', required: Which resource `id` names. `account` is an Account (`sa_group_`) and sets the cash-side account of its transactions; `virtual_account` (`subaccount_`), `card` (`c_`), `card_group` (`card_group_`), `merchant` (`merchant_v2_`, from a card transaction's `details.merchant.id`), `merchant_category` (`merchant_category_`, from a card transaction's `details.merchant.categoryId`) and `recipient` (the recipient of a transfer) code the expense side of matching transactions; `accounts_payable` takes no `id` and sets the accounts payable account bills are posted to. When several rules reach the same dimension of one transaction the more specific source wins, from weakest to strongest: `virtual_account`, `card_group`, `card`, `merchant_category`, `merchant`, `recipient`.
    - `id` string: The id of that resource. Required for every type except `accounts_payable`.
  - `dimensionKey` string, required: The dimension this mapping codes, a `key` from `GET /v2/accounting/dimensions`.
  - `valueId` string: The dimension value applied, from `GET /v2/accounting/dimensions/{dimensionKey}/values`. Absent on custom-field mappings, which carry `customFieldValue` instead.
  - `customFieldValue` union: The custom field value applied, present only when `dimensionKey` is a `custom_field` dimension. Its shape follows the field's `fieldType`: an option value for `select`, a list of option values for `multiselect`, otherwise a boolean, string or number.
    - string
    - number
    - boolean
    - string[]
  - `createdBy` 'user' | 'ai': `user` for mappings written by people or the API, `ai` for mappings the accounting intelligence agent proposed and applied.
  - `createdAt` string, date-time, required

## Other responses

- `400`: - `connection_id_required` — The legal entity has several accounting connections, so the request must say which one with `connectionId`. List them with `GET /v2/accounting/connections`. - `custom_field_value_invalid` — The custom field does not exist in this scope, or the value does not match its type or options. `problem` says which. - `dimension_disabled` — The dimension is turned off for coding. Turn it on with `PATCH /v2/accounting/dimensions/{dimensionKey}`. - `dimension_not_mappable` — The dimension only makes sense per entry, so mappings cannot set it. Its `mappable` is `false`. - `dimension_value_disabled` — The value is turned off for coding. Turn it on with `PATCH /v2/accounting/dimensions/{dimensionKey}/values/{valueId}`. - `mapping_source_not_allowed` — This kind of source cannot set this dimension, for example an account on a class. - `mapping_value_mismatch` — Custom field dimensions take `customFieldValue`; every other dimension takes `valueId`. `expected` names the one this dimension takes. - `invalid_request (request shape)` — The body, query, or headers failed validation, or a required header is missing. `details` has one entry per failing location, keyed by JSON pointer or header name.
- `401`: - `unauthorized` — API key authentication is missing or invalid.
- `403`: - `forbidden` — The credential is not permitted to perform this action on the resource. When the resource is a field of the request, `details` names that `field` and the `id` it received. - `forbidden (legal entity)` — The credential is not permitted to act for the selected legal entity. - `not_available` — Public API v2 is not yet available. Use [Public API v1](https://docs.slash.com/introduction) in the meantime. - `user_api_key_required` — The API key is scoped to a legal entity rather than a user. Every v2 request needs a user API key, created under Settings → API keys in the Slash dashboard, together with the `x-legal-entity` header.
- `404`: - `not_found` — No resource matches the identifier. When the identifier is a field of the request, `details` names that `field` and the `id` it received.
- `409`: - `default_subsidiary_required` — The platform keeps mappings per subsidiary, and the connection has no default subsidiary to read or write them for.
- `429`: The request exceeded the applicable rate limit. The response body is plain text, not the error object; clients must not depend on its wording.
- `500`: - `internal` — Slash could not complete the request. Quote `referenceId` when contacting Slash support.

## Changes

- **2026-10-16** `8b5d371ffeea`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/slashfi/apis/slash-public-api/changes/v2/accounting/mappings/put.md)

---

[API](https://skmtc.dev/slashfi/apis/slash-public-api.md) - [All operations](https://skmtc.dev/slashfi/apis/slash-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/slashfi/apis/slash-public-api/revisions/eaed2d63c9e2?raw)
