---
title: "Attach a document to an accounting entry"
method: POST
path: "/v2/accounting/entries/{entryId}/attachments"
---

# Attach a document to an accounting entry

`POST /v2/accounting/entries/{entryId}/attachments`

## Request

- Base URL: `https://api.slash.com`
- URL: `https://api.slash.com/v2/accounting/entries/{entryId}/attachments`
- Auth: API key in header `X-API-Key`

Attach an uploaded document, such as a receipt, to an entry. It's sent to the accounting platform with the entry's next sync.

## Request body

- object
  - `documentId` string, required: A document uploaded with purpose `accounting_receipt`.

## Response `200`

The entry with the document attached.

- AccountingEntry: The accounting record for one settled transaction (or group of related transactions) or one bill. An entry is created automatically when its source settles, coded with dimensions on its line items, and then synced to the connected platform. `status` tracks that lifecycle.
  - `id` string, required: Entry id with the `accounting_entry_` prefix.
  - `connectionId` string, required: The accounting connection the entry belongs to.
  - `type` 'unknown' | 'expense' | 'bank_transfer' | 'bank_deposit' | 'journal_entry' | 'expense_card' | 'expense_card_refund' | 'bill_payment' | 'bill', required: What the entry represents on the platform. `expense_card` and `expense_card_refund` come from card transactions; `bank_transfer`, `bank_deposit`, and `expense` from account transactions; `journal_entry` from transactions posted as journals; `bill` is the accounts-payable bill and `bill_payment` the transaction that settles one. `unknown` entries have not yet been classified.
  - `status` 'in_review' | 'ready_to_sync' | 'pending_sync' | 'syncing' | 'synced' | 'archived' | 'failed', required: `in_review` until a user or rule marks it ready; `ready_to_sync` when coding is complete; `pending_sync` and `syncing` while a sync is queued or in flight; `synced` once the platform holds it; `failed` when the platform rejected it (see `lastSyncError`); `archived` when excluded from the books.
  - `statusUpdatedAt` string, date-time, required: When `status` last changed.
  - `date` string, date, required: Accounting date as `YYYY-MM-DD`: the settlement date of the source transaction or the invoice date of the bill.
  - `memo` string: Memo sent to the platform.
  - `amount` Money, required: A signed monetary amount expressed in minor units.
    - `amount` integer, required: Amount in the currency's minor units.
    - `currency` string, required: Uppercase ISO 4217 currency code.
  - `source` object, required: What the entry was created from.
    - `type` 'transaction' | 'bill', required: `transaction` entries reference a transaction; `bill` entries reference a bill from `GET /v2/bills/{billId}`.
    - `id` string, required: The transaction (`agg_tx_`) or bill (`bill_`) id. For transaction entries it is one of `transactionIds`.
  - `transactionIds` string[], required: Every transaction the entry covers. Usually one; internal transfers and card repayments combine two.
  - `lineItems` AccountingLineItem[], required: Ordered `fixed` lines first, then `editable` lines by `splitIndex`.
    - `id` string, required: Line item id with the `accounting_line_item_` prefix.
    - `type` 'fixed' | 'editable', required: `fixed` lines are set by Slash from the connection's account mappings and cannot be recoded. `editable` lines carry the dimensions you code.
    - `amount` Money, required: A signed monetary amount expressed in minor units.
      - `amount` integer, required: Amount in the currency's minor units.
      - `currency` string, required: Uppercase ISO 4217 currency code.
    - `description` string: Line memo sent to the platform.
    - `splitIndex` integer, required: Position of the line among the entry's `editable` lines; `0` for unsplit entries.
    - `transactionId` string: For transaction entries, the transaction this line settles. Entries that combine several transactions carry one `fixed` line per transaction.
    - `dimensions` object, required: The line's coding, keyed by dimension key (see `GET /v2/accounting/dimensions`). Only dimensions with a value are present.
    - `customFields` object, required: Raw values of line-item level custom fields, keyed by the field's `fieldKey` from `GET /v2/accounting/dimensions`. Value type follows the field's `fieldType`: strings, numbers, booleans, or arrays of option values for `multiselect`.
  - `lineItemLevelDimensions` string[], required: For `bill` entries, the dimension keys coded per line item. Dimensions not listed take the same value on every line. Empty for transaction entries.
  - `entryLevelDimensions` string[], required: Dimension keys the platform records once per entry rather than per line item. Every line item carries the same value for these, and a split cannot code them differently across its lines.
  - `unsupportedDimensions` string[], required: Dimension keys the platform does not accept for this entry `type`. Any value set on them is dropped at sync time.
  - `customFields` object, required: Raw values of entry level custom fields, keyed by the field's `fieldKey` from `GET /v2/accounting/dimensions`.
  - `attachments` AccountingAttachment[], required
    - `id` string, required: Attachment id with the `accounting_attachment_` prefix.
    - `documentId` string, required: The underlying document.
    - `filename` string, required
    - `contentType` string: MIME type of the file.
    - `status` 'pending_sync' | 'synced' | 'failed', required: `pending_sync` until the entry has synced and the file has been pushed; `synced` once the platform holds a copy; `failed` when the push was rejected.
  - `externalId` string: The platform's id for the synced record. Present once `status` is `synced`.
  - `externalUrl` string, uri: A link to the record in the platform, when the platform provides one.
  - `lastSyncError` object: Why the most recent sync attempt failed. Present while `status` is `failed`.
    - `code` string, required: Snake_case code from Slash's accounting error catalog, or `sync_error` when the failure isn't one Slash recognizes.
    - `message` string, required: What went wrong, in words you can show a user. For unrecognized failures this is the platform's own explanation when it gives one.
    - `title` string, required: Short summary of the failure.
    - `suggestion` string, required: How to fix it.
  - `createdAt` string, date-time, required
  - `updatedAt` string, date-time, required

## Other responses

- `400`: - `bill_entry_field_read_only` — A bill entry takes its lines, amounts, descriptions, memo and files from the bill, so only its coding changes here. - `document_purpose_mismatch` — The document was uploaded with a different `purpose`. - `unsupported_file_type` — Only PDF, PNG and JPEG files are accepted, and only PNG and JPEG for invoice logos. HEIC photos are converted to JPEG on upload. - `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`: - `bill_payment_entry_read_only` — Bill payment entries take their coding from the bill they pay. Code the bill’s entry instead.
- `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/entries/:entryId/attachments/post.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)
