# Tool Reference

Complete technical reference for the Kick MCP tool surface. Every tool executes through the Kick REST API under the same auth, workspace, permission, and audit checks as the web app.

***

## Auth & Transport

```
Endpoint:  https://use.kick.co/mcp
Auth:      Authorization: Bearer kick_pat_...
OAuth:     https://use.kick.co/.well-known/oauth-protected-resource
Scopes:    mcp:read · mcp:write
```

Workspace-scoped PATs auto-inject their bound workspace. User-scoped PATs and OAuth tokens must pass `workspaceId` in inputs where required.

***

## Conventions

### Confirmation flow (write tools)

All write tools are preview-first.

1. Call the tool **without** `confirmationToken` → receive a `preview` object describing the action and a fresh token
2. Re-call with the **same input** plus the returned `confirmationToken` → mutation executes

```json
// preview response
{ "preview": { "action": "transactions_update", "confirmationToken": "...", "summary": "Update transaction 12345.", "input": { ... } } }
```

Never invent or reuse a token. Each preview issues a new token bound to the exact input.

### List output

```json
{ "rows": [object], "fields": ["id", "..."], "total": 123, "hasMore": false, "nextCursor": null }
```

`fields` projects which columns appear in `rows`. `nextCursor` is `null` when there's no more data.

### Pagination types

* **Page cursor** — 1-based string (`"1"`, `"2"`...). Used by most list endpoints.
* **Offset cursor** — 0-based string (`"0"`, `"100"`...). Used by accounting, rule transactions, and similar endpoints.

### Common ID types

* `workspaceId` — UUID v7 string
* `entityId` — positive integer (not a UUID)
* `transactionId`, `financialAccountId`, `financialDocumentId` — positive integer
* `ruleId`, `groupId`, `categoryId`, `counterpartyId`, `classId`, `accountId`, `journalEntryId` — UUID v7 string

### Tool selection patterns

| Goal                                             | Reach for                                                        |
| ------------------------------------------------ | ---------------------------------------------------------------- |
| Resolve a workspace/client name to an id         | `workspaces_search` → `workspaces_get`                           |
| Bootstrap orientation for a workspace            | `workspace_context_get`                                          |
| Resolve a transaction by description/date/amount | `transactions_find` → `transactions_get`                         |
| Find both sides of a transfer                    | `transactions_suggested_matches` → `transactions_match_transfer` |
| Find a category/class/counterparty by name       | `*_search` (not `*_list`)                                        |
| Audit what changed and possibly undo             | `activity_list` → `activity_details_get` → `activity_revert`     |

***

## Transactions

### `transactions_find`

`GET /transactions` · **read** · idempotent

Find transactions in a workspace with pagination, filters, sorting, and projected fields. Use before transaction mutations to resolve numeric transaction ids and surface date, amount, description, counterparty, and category context.

```json
{
  "workspaceId": "019e2df8-d291-7a06-9958-602ffc4e9b71",
  "since": "2026-01-01",
  "until": "2026-01-31",
  "limit": 25,
  "fields": ["id", "date", "amount", "bank_description"]
}
```

`filters` is the same object used by the transaction table — `reviewState`, `status`, `categoryIds`, `counterpartyIds`, `financialAccountIds`, `search`, `amountMin`, `amountMax`, and more.

**reviewState:** `REVIEWED` · `UNREVIEWED` · **status:** `pending` · `completed` · `failed`

***

### `transactions_get`

`GET /transactions/:id` · **read** · idempotent

Get one transaction by numeric id when full transaction details are needed after `transactions_find`. Use before sensitive updates or deletes to confirm human-readable date, amount, description, accounts, category, counterparty, and split details.

```json
{ "transactionId": 12345 }
```

***

### `transactions_statistics`

`GET /transactions/statistics` · **read** · idempotent

Aggregate counts and totals using the same filter semantics as `transactions_find`. Use for counts, totals, or review summaries before fetching detailed transaction rows.

```json
{ "workspaceId": "019e2df8-...", "filters": {} }
```

***

### `transactions_suggested_matches`

`GET /transactions/:id/suggested-matches` · **read** · idempotent

Suggested transfer-match candidates within the matching date window. Use this before `transactions_match_transfer` when the user has not identified both sides of a transfer pair. Supports limit/cursor and field projection.

```json
{ "transactionId": 12345, "fields": ["id", "date", "amount", "display_description"] }
```

***

### `transactions_similar_ids`

`GET /transactions/:id/similar` · **read** · idempotent

List similar transaction ids. The underlying similarity API returns ids only — `fields` is restricted to `["id"]`. Offset cursor; default limit 100, max 500.

```json
{ "transactionId": 12345, "fields": ["id"], "limit": 100 }
```

***

### `transactions_update`

`PATCH /transactions/:id` · **write** · destructive · confirm

Update bookkeeping fields on one transaction (memo, category, class, counterparty, entity, review state). Requires a numeric transaction id — search transactions first when only a description, amount, or date is known.

```json
{
  "transactionId": 12345,
  "payload": { "memo": "Owner reviewed" }
}
```

Payload fields: `memo`, `categoryId`, `classId`, `counterpartyId`, `entityId`, `reviewState` (`"REVIEWED"` | `"UNREVIEWED"`).

***

### `transactions_bulk_update`

`POST /transactions/:workspaceId/bulk-update` · **write** · destructive · confirm

Apply bookkeeping updates to multiple Kick transactions in a workspace. Use only after the target transaction ids and intended changes are clear and human-readable details have been reviewed.

```json
{
  "workspaceId": "019e2df8-...",
  "payload": {
    "transactions": [
      { "transactionId": 12345, "memo": "Reviewed by agent" },
      { "transactionId": 12346, "memo": "Reviewed by agent" }
    ]
  }
}
```

***

### `transactions_update_splits`

`PUT /transactions/:id/splits/v2` · **write** · destructive · confirm

Replace split lines for one transaction. Use when allocating one transaction across multiple entities, categories, amounts, classes, counterparties, or accounts. Requires a non-empty `payload.splits` array.

```json
{
  "transactionId": 12345,
  "payload": {
    "splits": [
      { "entityId": 123, "amount": 80, "splitDescription": "Office supplies", "categoryId": "019e2dec-..." },
      { "entityId": 123, "amount": 45, "splitDescription": "Shipping", "categoryId": "019e2dec-..." }
    ]
  }
}
```

***

### `transactions_bulk_unsplit`

`POST /transactions/:workspaceId/bulk-unsplit` · **write** · destructive · confirm

Restore one or more split transactions back to their unsplit parent state. Only run after reviewing the split lines that will be removed.

```json
{
  "workspaceId": "019e2df8-...",
  "payload": { "transactionIds": [12345, 12346] }
}
```

***

### `transactions_match_transfer`

`POST /transactions/:originTransactionId/match-transfer` · **write** · destructive · confirm

Match two transactions as a transfer pair. Use `transactions_suggested_matches` first when the user has not identified both transaction ids. Show both dates, amounts, descriptions, and accounts before confirmation.

```json
{
  "originTransactionId": 12345,
  "payload": { "targetTransactionId": 12346 }
}
```

***

### `transactions_unmatch_transfer`

`DELETE /transactions/:financialTransactionId/match-transfer` · **write** · destructive · confirm

Remove an existing transfer match from a transaction.

```json
{ "financialTransactionId": 12345 }
```

***

### `transactions_link_document`

`POST /transactions/link` · **write** · destructive · confirm

Link a financial document to a transaction. Use when both the document id and transaction id are known, or after document and transaction lookup.

```json
{
  "payload": { "financialDocumentId": 34567, "financialTransactionId": 12345 }
}
```

***

### `transactions_detach_document_match`

`POST /transactions/:financialTransactionId/detach/:matchId` · **write** · destructive · confirm

Detach a financial document match from a transaction.

```json
{ "financialTransactionId": 12345, "matchId": 34567 }
```

***

### `manual_transactions_create`

`POST /manual-transaction` · **write** · destructive · confirm

Create one or more manual transactions in Kick. For user-approved bookkeeping entries not imported from a connected financial account.

```json
{
  "payload": {
    "transactions": [
      { "entityId": 123, "date": "2026-01-31", "amount": 125, "description": "Owner contribution" }
    ]
  }
}
```

***

### Transaction deletion lifecycle

Soft delete → cancel (restore) **or** finalize (hard delete). All four steps are confirmation-gated.

#### `transactions_delete_mark_for_deletion`

`DELETE /delete-transaction/soft/:transactionId` · **write** · destructive · confirm

Mark a transaction for deletion without finalizing. Reversible.

```json
{ "transactionId": 12345 }
```

#### `transactions_delete_bulk_mark_for_deletion`

`POST /delete-transaction/soft/bulk` · **write** · destructive · confirm

Bulk soft-delete.

```json
{ "payload": { "transactionIds": [12345, 12346] } }
```

#### `transactions_delete_cancel_deletion`

`POST /delete-transaction/restore/:transactionId` · **write** · destructive · confirm

Restore a soft-deleted transaction.

```json
{ "transactionId": 12345 }
```

#### `transactions_delete_finalize_deletion`

`DELETE /delete-transaction/hard/:transactionId` · **write** · destructive · confirm

Permanently delete a soft-deleted transaction. **Irreversible.**

```json
{ "transactionId": 12345 }
```

***

## Documents

### `documents_search`

`GET /financial-document` · **read** · idempotent

Search financial documents in a workspace by filename and metadata filters. Use to resolve numeric `financialDocumentId` before attaching documents to transactions or manual journal entries. **Does not** search OCR text, return file bytes, or expose download URLs directly.

```json
{
  "workspaceId": "019e2df8-...",
  "search": "Book adjusting entries",
  "limit": 10,
  "fields": ["financialDocumentId", "fileName", "period", "uploader", "documentCategory", "matchCount"]
}
```

***

### `documents_get_metadata`

`GET /financial-document/:financialDocumentId` · **read** · idempotent

Safe metadata for one financial document by numeric id. Same numeric id used in Kick `/documents/:id` URLs and document-linking tools. Metadata only — no file bytes, storage paths, or download URLs.

```json
{
  "financialDocumentId": 12345,
  "fields": ["financialDocumentId", "fileName", "period", "entity", "financialAccount"]
}
```

***

### `documents_request_upload`

`POST /financial-document/mcp-upload-url` · **write** · non-destructive

**Step 1 of upload.** Returns a presigned upload URL, a curl command, and an `uploadToken`. After uploading the file with the returned curl, call `documents_confirm_upload`.

```json
{
  "workspaceId": "019e2df8-...",
  "fileName": "chase-statement-jan-2026.pdf"
}
```

***

### `documents_confirm_upload`

`POST /financial-document/mcp-confirm-upload` · **write** · idempotent

**Step 2 of upload.** Triggers extraction and classification.

```json
{ "uploadToken": "eyJ2IjoxLC..." }
```

***

### `documents_download`

`POST /financial-document/mcp-download` · **read** · idempotent

Returns a presigned download URL. URL expires after a few minutes.

```json
{ "documentId": 12345 }
```

***

## Rules

### `rules_groups_list`

`GET /rule-groups/:workspaceId` · **read** · idempotent

List rule groups and compact rule summaries. Use to resolve rule and group ids before rule mutations, and to show rule order, group names, and default status.

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "name", "order", "rules"],
  "limit": 100
}
```

Result extends listResult with `{ counterparties: [{id, name, workspaceId}], normalizedDescriptions, transactionCounts }`.

***

### `rules_accounting_defaults`

`GET /rule-groups/:workspaceId/accounting-default-rules` · **read** · idempotent

Get the single accounting-defaults rule group for a workspace. Always returns exactly one group.

```json
{ "workspaceId": "019e2df8-...", "fields": ["id", "name", "rules"], "limit": 1 }
```

***

### `rules_normalized_descriptions`

`GET /rule-groups/:workspaceId/normalized-descriptions` · **read** · idempotent

Normalized transaction descriptions used by rule conditions. Use to find stable description values before creating description-based rules.

```json
{
  "workspaceId": "019e2df8-...",
  "search": "stripe",
  "fields": ["normalizedDescriptionId", "normalizedDescription", "sampleBankDescription"],
  "limit": 25
}
```

***

### `rules_matching_transactions`

`POST /rule-groups/:workspaceId/get-matching-transactions` · **read** · idempotent

Preview transactions matching a rule payload **before creating it.**

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "date", "amount", "displayDescription"],
  "limit": 25,
  "payload": {
    "groupType": "transaction",
    "conditions": [
      { "conditionType": "counterparty", "value": "stripe", "transferDirection": "from" }
    ],
    "splitActionConfig": {
      "isPercentage": true,
      "splits": [
        { "categoryId": "019e2dec-...", "amount": 100, "entityId": 123, "splitDescription": "Software subscription" }
      ]
    },
    "excludeSplitTransactions": true
  }
}
```

***

### `rules_matching_transfers`

`POST /rule-groups/:workspaceId/get-matching-transfer-transactions` · **read** · idempotent

Preview transfer matches for a transfer rule payload.

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["transactionId", "transactionDisplayDescription", "matchId", "matchDisplayDescription"],
  "limit": 25,
  "payload": {
    "conditions": [
      { "conditionType": "counterparty", "value": "payroll", "transferDirection": "from" }
    ],
    "excludeMatchedTransfers": true,
    "matchingMode": "allow"
  }
}
```

***

### `rules_applied_transactions`

`POST /rule-groups/:workspaceId/rule/:ruleId/applied-transactions` · **read** · idempotent

Transactions currently affected by an existing rule.

```json
{
  "workspaceId": "019e2df8-...",
  "ruleId": "01979b94-c177-...",
  "fields": ["id", "date", "amount", "displayDescription"],
  "limit": 25,
  "payload": {}
}
```

***

### `rules_applied_transfers`

`POST /rule-groups/:workspaceId/rule/:ruleId/applied-transfer-transactions` · **read** · idempotent

Transfers currently affected by an existing transfer rule. Result includes `mode: "allow" | "disallow"`.

```json
{
  "workspaceId": "019e2df8-...",
  "ruleId": "01979b94-...",
  "fields": ["transactionId", "transactionDisplayDescription", "matchId", "matchDisplayDescription"],
  "limit": 25,
  "payload": {}
}
```

***

### `rules_create`

`POST /rule-groups/:workspaceId/rule` · **write** · non-destructive · confirm

Create a transaction rule in a rule group. Resolve group, category, class, counterparty, or account ids with the corresponding search/list tools first.

```json
{
  "workspaceId": "019e2df8-...",
  "payload": {
    "rule": {
      "groupId": "01979b94-...",
      "conditions": [
        { "conditionType": "description_includes", "value": "Adobe", "transferDirection": null }
      ],
      "actions": [
        { "actionType": "category", "value": "01979b94-...", "transferDirection": null }
      ]
    },
    "source": "settings",
    "applyToExistingTransactions": false
  }
}
```

**`conditionType`:** `counterparty` · `category` · `suggested_category` · `description_is` · `description_includes` · `description_does_not_include` · `amount` · `date` · `financial_accounts` · `subaccounts` · `entity` · `date_proximity` · `class` · `similar_to` · `amount_is_round`

**`actionType`:** `category` · `entity` · `account_id` · `account_name` · `accrual_account_id` · `accrual_account_name` · `class` · `memo` · `counterparty` · `split` · `transfer_matching`

***

### `rules_update`

`PATCH /rule-groups/:workspaceId/rule/:ruleId` · **write** · destructive · confirm

Update conditions, actions, group, order, enabled state, or note on an existing rule.

```json
{
  "workspaceId": "019e2df8-...",
  "ruleId": "01979b94-...",
  "payload": {
    "rule": {
      "actions": [
        { "actionType": "category", "value": "01979b94-...", "transferDirection": null }
      ]
    },
    "applyToExistingTransactions": false
  }
}
```

***

### `rules_update_note`

`PATCH /rule-groups/:workspaceId/rule/:ruleId/note` · **write** · non-destructive · confirm

Update only the internal note on a rule. Pass `null` to clear.

```json
{
  "workspaceId": "019e2df8-...",
  "ruleId": "01979b94-...",
  "payload": { "note": "Review this rule after month-end close." }
}
```

***

### `rules_change_order`

`PATCH /rule-groups/:workspaceId/rule/:ruleId/order` · **write** · destructive · confirm

Move a rule to an absolute execution order. Execution order determines which rule wins.

```json
{
  "workspaceId": "019e2df8-...",
  "ruleId": "01979b94-...",
  "payload": { "groupId": "01979b94-...", "order": 2 }
}
```

***

### `rules_delete`

`DELETE /rule-groups/:workspaceId/rule/:ruleId` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df8-...", "ruleId": "01979b94-..." }
```

***

### `rules_groups_create`

`POST /rule-groups/:workspaceId/group` · **write** · non-destructive · confirm

Create a rule group. Choose an `order` that does not conflict with existing groups.

```json
{
  "workspaceId": "019e2df8-...",
  "payload": { "name": "Software subscriptions", "order": 3, "type": "transaction", "icon": "receipt" }
}
```

**`type`:** `transaction` · `accounting` · `transfer` · `split`

***

### `rules_groups_update`

`PATCH /rule-groups/:workspaceId/group/:groupId` · **write** · destructive · confirm

```json
{
  "workspaceId": "019e2df8-...",
  "groupId": "01979b94-...",
  "payload": { "name": "SaaS subscriptions", "order": 3 }
}
```

***

### `rules_groups_delete`

`DELETE /rule-groups/:workspaceId/group/:groupId` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df8-...", "groupId": "01979b94-..." }
```

***

## Categories

### `categories_list`

`GET /category/:workspaceId` · **read** · idempotent

List categories for catalog browsing. Use `categories_search` for name-to-id resolution before category mutations.

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "label", "parentLabel", "taxonomy"],
  "limit": 100
}
```

***

### `categories_search`

`GET /category/:workspaceId/search` · **read** · idempotent

Search standard plus workspace-custom categories by label, path, parent label, or taxonomy. If multiple plausible rows are returned, ask the user to choose using path, scope, and workspaceId.

```json
{ "workspaceId": "019e2df8-...", "search": "Legal", "limit": 10 }
```

***

### `categories_list_global`

`GET /category/global` · **read** · idempotent

```json
{ "fields": ["id", "label", "parentLabel", "taxonomy"], "limit": 100, "search": "Legal" }
```

***

### `categories_statistics`

`GET /category/:workspaceId/statistics` · **read** · idempotent

Bounded transaction statistics grouped by category. Useful before changing, deleting, or auditing categories.

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "label", "total", "count"],
  "limit": 100
}
```

***

### `categories_create`

`POST /category/:workspaceId` · **write** · non-destructive · confirm

```json
{
  "workspaceId": "019e2df8-...",
  "payload": {
    "label": "AI tools",
    "description": "Subscriptions for AI-assisted software.",
    "parentCategoryId": "01979b94-..."
  }
}
```

***

### `categories_update`

`PATCH /category/:workspaceId/:categoryId` · **write** · destructive · confirm

```json
{
  "workspaceId": "019e2df8-...",
  "categoryId": "01979b94-...",
  "payload": { "label": "AI software", "description": "AI and automation subscriptions." }
}
```

***

### `categories_delete`

`DELETE /category/:workspaceId/:categoryId` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df8-...", "categoryId": "01979b94-..." }
```

***

## Counterparties

### `counterparties_list`

`GET /counterparty/:workspaceId` · **read** · idempotent

```json
{ "workspaceId": "019e2df8-...", "limit": 100 }
```

***

### `counterparties_create`

`POST /counterparty` · **write** · non-destructive · confirm

Search existing counterparties first to avoid duplicates.

```json
{
  "workspaceId": "019e2df8-...",
  "payload": {
    "name": "Northwind Supplies",
    "email": "billing@northwind.example",
    "website": "https://northwind.example"
  }
}
```

***

### `counterparties_update`

`PATCH /counterparty/:workspaceId/:counterpartyId` · **write** · destructive · confirm

```json
{
  "workspaceId": "019e2df8-...",
  "counterpartyId": "01979b94-...",
  "payload": { "name": "Northwind Supply Co.", "website": "https://northwind.example" }
}
```

***

### `counterparties_delete`

`DELETE /counterparty/:workspaceId/:counterpartyId` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df8-...", "counterpartyId": "01979b94-...", "force": false }
```

***

### `counterparties_merge`

`POST /counterparty/:workspaceId/merge` · **write** · destructive · confirm

Merge a duplicate into the canonical counterparty to keep.

```json
{
  "workspaceId": "019e2df8-...",
  "counterpartyToMergeId": "01979b94-...",
  "counterpartyToKeepId": "01979b94-..."
}
```

***

### `counterparties_copy_global`

`POST /counterparty/copy-global-to-local` · **write** · destructive · confirm

Copy a global template into the workspace with optional field overrides.

```json
{
  "workspaceId": "019e2df8-...",
  "globalCounterpartyId": "01979b94-...",
  "update": { "website": "https://northwind.example" }
}
```

***

## Classes

Classes require the `CLASSES` premium feature.

### `classes_list`

`GET /class/:workspaceId` · **read** · idempotent

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "label", "path", "parentLabel"],
  "limit": 100
}
```

***

### `classes_search`

`GET /class/:workspaceId/search` · **read** · idempotent

```json
{ "workspaceId": "019e2df8-...", "search": "Location", "limit": 10 }
```

***

### `classes_statistics`

`GET /class/:workspaceId/statistics` · **read** · idempotent

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "label", "total", "count"],
  "limit": 100
}
```

***

### `classes_transaction_counts`

`GET /class/:workspaceId/transactions-count` · **read** · idempotent

Use before deleting or reorganizing classes to check usage.

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "label", "count"],
  "limit": 100
}
```

***

### `classes_create`

`POST /class/:workspaceId` · **write** · non-destructive · confirm

```json
{
  "workspaceId": "019e2df8-...",
  "label": "New York",
  "parentClassId": "01979b94-..."
}
```

***

### `classes_update`

`PATCH /class/:workspaceId/:id` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df8-...", "classId": "01979b94-...", "label": "NY Office" }
```

***

### `classes_delete`

`DELETE /class/:workspaceId/:id` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df8-...", "classId": "01979b94-..." }
```

***

## Reports

All report tools are **read · idempotent**.

### Common accounting report inputs

Used by P\&L, Balance Sheet, Cash Flow, Trial Balance:

| Field                               | Type            | Required | Notes                                                                   |
| ----------------------------------- | --------------- | -------- | ----------------------------------------------------------------------- |
| `entityId`                          | integer         | yes      | numeric entity id, not workspaceId                                      |
| `ledgerId`                          | uuid string     | yes      | from `ledgers_list`                                                     |
| `startDate`                         | `yyyy-MM-dd`    | yes      |                                                                         |
| `endDate`                           | `yyyy-MM-dd`    | yes      |                                                                         |
| `cycle`                             | enum            | no       | `week` · `month` · `quarter` · `year` · `entity` · `class` · `subclass` |
| `comparison`                        | enum            | no       | comparison period selector                                              |
| `comparisonDiff`                    | enum            | no       | difference display mode                                                 |
| `comparisons`                       | enum\[] (max 2) | no       | P\&L and Balance Sheet only                                             |
| `comparisonDiffs`                   | enum\[] (max 2) | no       |                                                                         |
| `ratioTypes`                        | enum\[] (max 2) | no       | adds ratio columns                                                      |
| `classes`                           | string\[]       | no       | class ids                                                               |
| `classFilterType`                   | enum            | no       | how to apply class filter                                               |
| `counterpartiesIds`                 | uuid\[]         | no       |                                                                         |
| `withEmptyOrUnverifiedCounterparty` | boolean         | no       |                                                                         |

***

### `reports_profit_loss_get`

`GET /accounting-reports/profit-loss`

```json
{
  "entityId": 123,
  "ledgerId": "11111111-1111-7111-8111-111111111111",
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "cycle": "month",
  "includeCounterpartyBreakdown": false
}
```

***

### `reports_balance_sheet_get`

`GET /accounting-reports/balance-sheet`

Common accounting inputs.

```json
{
  "entityId": 123,
  "ledgerId": "11111111-...",
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "cycle": "month"
}
```

***

### `reports_cash_flow_statement_get`

`GET /accounting-reports/cash-flow-statement`

Common accounting inputs (single comparison only).

```json
{
  "entityId": 123,
  "ledgerId": "11111111-...",
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "cycle": "month"
}
```

***

### `reports_trial_balance_get`

`GET /accounting-reports/trial-balance`

Common accounting inputs + pagination: `limit` (1–250, default 100), `cursor` (offset), `fields` (`["key", "label", "values"]`), `search?`.

```json
{
  "entityId": 123,
  "ledgerId": "11111111-...",
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "limit": 100,
  "fields": ["key", "label", "values"]
}
```

***

### `reports_account_transactions_get`

`GET /accounting-reports/account-transactions`

Journal entry rows for one or more accounts.

```json
{
  "entityId": 123,
  "ledgerId": "11111111-...",
  "startDate": "2026-01-01",
  "endDate": "2026-01-31",
  "accountCodes": [1000]
}
```

Optional filters: `classifications` (`AccountClass[]`), `sourceTypes` (`JournalEntrySourceFilter[]`), `minAmount`, `maxAmount`, `pnlBalanceSince`, plus class and counterparty filters.

***

### `reports_chart_of_accounts_get`

`GET /accounting-reports/chart-of-accounts/:workspaceId`

```json
{ "workspaceId": "11111111-1111-4111-8111-111111111111" }
```

Optional: `ledgerId`, `availableClassifications` (`AccountClass[]`), pagination fields, `search`.

***

### `reports_expenses_by_vendor_get`

`GET /accounting-reports/expenses-by-vendor`

Common accounting inputs + pagination (`limit`, `cursor`, `fields`, `search`).

```json
{
  "entityId": 123,
  "ledgerId": "11111111-...",
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "cycle": "month"
}
```

***

### `reports_owner_cash_flow_get`

`GET /owner-reports/cash-flow`

Multi-entity owner cash flow.

```json
{
  "entityIds": [123],
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "cycle": "month"
}
```

Optional: `accountIds`, `category`, `classes`, `classFilterType`.

***

### `reports_top_transactions_get`

`GET /owner-reports/cash-flow/top-transactions`

```json
{
  "entityIds": [123],
  "startDate": "2026-01-01",
  "endDate": "2026-03-31",
  "categoryIdentifier": "income"
}
```

***

## Chart of Accounts

### `accounts_list`

`GET /accounting/accounts/:entityId` · **read** · idempotent

List chart-of-accounts rows for one entity.

```json
{
  "entityId": 123,
  "fields": ["id", "code", "name", "type", "subtype"],
  "limit": 100
}
```

Optional: `accountCodes` (integer\[] max 100), `search`, `ledgerBasis` (`"cash" | "accruals"`, accrual mode only).

***

### `accounts_get_for_workspace`

`GET /accounting/accounts/workspace/:workspaceId` · **read** · idempotent

Flattened account catalog across entities. Default fields include `entityId`.

```json
{
  "workspaceId": "019e2df8-...",
  "search": "Meals",
  "fields": ["entityId", "id", "code", "name", "type"],
  "limit": 100
}
```

***

### `accounts_create`

`POST /accounting/accounts/create/:workspaceId` · **write** · non-destructive · confirm

```json
{
  "workspaceId": "019e2df9-...",
  "payload": {
    "name": "Office supplies",
    "type": "Operating Expenses",
    "subtype": "Office Expenses",
    "entityIds": [123],
    "parentGroupId": "019e2df9-..."
  }
}
```

***

### `accounts_update`

`PATCH /accounting/accounts/:entityId/:id` · **write** · destructive · confirm

```json
{
  "entityId": 123,
  "accountId": "019e2df9-...",
  "payload": { "name": "Office supplies and equipment" }
}
```

***

### `accounts_bulk_update`

`PATCH /accounting/accounts/bulk-update` · **write** · destructive · confirm

```json
{
  "payload": {
    "accounts": [
      { "accountId": "019e2df9-...", "entityId": 123 },
      { "accountId": "019e2df9-...", "entityId": 123 }
    ],
    "name": "Reviewed account name"
  }
}
```

***

### `accounts_bulk_disable`

`POST /accounting/accounts/bulk-disable` · **write** · destructive · confirm

```json
{
  "payload": [
    { "accountId": "019e2df9-...", "entityId": 123 },
    { "accountId": "019e2df9-...", "entityId": 123 }
  ]
}
```

***

### `accounts_bulk_enable`

`POST /accounting/accounts/bulk-enable` · **write** · non-destructive · confirm

Same payload shape as `accounts_bulk_disable`.

***

### `accounts_bulk_delete`

`POST /accounting/accounts/bulk-delete` · **write** · destructive · confirm

Same payload shape as `accounts_bulk_disable`.

***

### `accounts_merge`

`POST /accounting/accounts/:entityId/merge` · **write** · destructive · confirm

Source is merged into target — balances and transactions move to target.

```json
{
  "entityId": 123,
  "payload": {
    "sourceAccountId": "019e2df9-...",
    "targetAccountId": "019e2df9-..."
  }
}
```

***

### `account_groups_create`

`POST /accounting/account-groups/:workspaceId` · **write** · non-destructive · confirm

```json
{
  "workspaceId": "019e2df9-...",
  "payload": {
    "name": "Operating expenses",
    "class": "Expenses",
    "initialChildAccountIds": ["019e2df9-..."]
  }
}
```

**`class`:** `Assets` · `Liabilities` · `Equity` · `Income` · `Expenses`

***

### `account_groups_update`

`PATCH /accounting/account-groups/:workspaceId/:id` · **write** · destructive · confirm

```json
{
  "workspaceId": "019e2df9-...",
  "groupId": "019e2df9-...",
  "payload": { "name": "Operating expenses", "accountIds": ["019e2df9-..."] }
}
```

***

### `account_groups_delete`

`DELETE /accounting/account-groups/:workspaceId/:id` · **write** · destructive · confirm

```json
{ "workspaceId": "019e2df9-...", "groupId": "019e2df9-..." }
```

***

## Ledger Setup

### `ledgers_list`

`GET /accounting/ledgers` · **read** · idempotent

One row per ledger per entity. Ledger APIs don't return entity names — use `workspaces_get` if you need display names.

```json
{
  "entityIds": [123],
  "fields": ["id", "entityId", "basis"],
  "limit": 100
}
```

***

### `ledgers_get_for_entity`

`GET /accounting/ledgers/:entityId` · **read** · idempotent

```json
{
  "entityId": 123,
  "fields": ["id", "entityId", "basis"],
  "limit": 100
}
```

***

### `ledgers_create_for_entity`

`PUT /accounting/ledgers/:entityId` · **write** · non-destructive · confirm

Available only when accrual mode is enabled.

```json
{ "entityId": 123, "basis": "accruals" }
```

**`basis`:** `cash` · `accruals`

***

## Journal Entries & Manual Journals

### `journal_entries_get`

`GET /accounting/journal-entries/:entityId/:id` · **read** · idempotent

```json
{ "entityId": 123, "id": "01979b94-..." }
```

***

### `manual_journals_list`

`GET /accounting/journal-entries/manual/:entityId` · **read** · idempotent

```json
{
  "entityId": 123,
  "startDate": "2026-01-01",
  "endDate": "2026-01-31",
  "limit": 25
}
```

***

### `manual_journals_create`

`POST /accounting/journal-entries/manual/:entityId` · **write** · destructive · confirm

Debits must equal credits. Each line uses either `debitAmount` or `creditAmount` (the other is `null`).

```json
{
  "entityId": 123,
  "payload": {
    "date": "2026-01-31",
    "memo": "Month-end adjustment",
    "ledgerBasis": "cash",
    "lines": [
      {
        "debitAmount": 125,
        "creditAmount": null,
        "accountCode": 713000,
        "accountId": "01979b94-...",
        "description": "Office supplies adjustment"
      },
      {
        "debitAmount": null,
        "creditAmount": 125,
        "accountCode": 100000,
        "accountId": "01979b94-...",
        "description": "Cash offset"
      }
    ]
  }
}
```

***

### `manual_journals_bulk_create`

`POST /accounting/journal-entries/manual/:entityId/bulk` · **write** · destructive · confirm

Atomic 1–25 manual journals.

```json
{
  "entityId": 123,
  "payload": {
    "manualJournalEntries": [
      {
        "date": "2026-01-31",
        "memo": "Month-end adjustment",
        "ledgerBasis": "cash",
        "lines": [
          { "debitAmount": 125, "creditAmount": null, "accountCode": 713000, "accountId": "01979b94-...", "description": "Office supplies adjustment" },
          { "debitAmount": null, "creditAmount": 125, "accountCode": 100000, "accountId": "01979b94-...", "description": "Cash offset" }
        ]
      }
    ]
  }
}
```

***

### `manual_journals_update`

`PUT /accounting/journal-entries/manual/:entityId/:journalEntryId` · **write** · destructive · confirm

Full replacement — pass the complete updated entry.

```json
{
  "entityId": 123,
  "journalEntryId": "01979b94-...",
  "payload": {
    "date": "2026-01-31",
    "memo": "Updated month-end adjustment",
    "ledgerBasis": "cash",
    "lines": [ ... ]
  }
}
```

***

### `manual_journals_delete`

`DELETE /accounting/journal-entries/manual/:entityId/:journalEntryId` · **write** · destructive · confirm

```json
{ "entityId": 123, "journalEntryId": "01979b94-..." }
```

For recurring journals, optionally pass `payload: { recurringRuleUpdateType: "..." | null }`.

***

## Opening Balances

### `opening_balances_list`

`GET /accounting/opening-balance/:entityId` · **read** · idempotent

```json
{
  "entityId": 123,
  "fields": ["accountId", "accountCode", "accountName", "openingBalance"],
  "limit": 100
}
```

***

### `opening_balances_get`

`GET /accounting/opening-balance/:entityId/:accountId` · **read** · idempotent

```json
{
  "entityId": 123,
  "accountId": "01979b94-...",
  "fields": ["accountId", "openingBalance", "date"]
}
```

***

### `opening_balances_upsert`

`POST /accounting/opening-balance/:entityId/:accountId` · **write** · destructive · confirm

```json
{
  "entityId": 123,
  "accountId": "01979b94-...",
  "payload": {
    "openingBalance": {
      "date": "2026-01-01",
      "clearingAccountId": "01979b94-...",
      "clearingBalanceDescription": "Opening balance clearing",
      "lines": [
        { "description": "Opening balance", "balance": 1250 }
      ]
    }
  }
}
```

***

### `opening_balances_bulk_set`

`POST /accounting/opening-balance/:entityId/bulk` · **write** · destructive · confirm

```json
{
  "entityId": 123,
  "payload": {
    "openingBalances": [
      { "accountId": "01979b94-...", "balance": 1250, "description": "Opening balance" }
    ]
  }
}
```

***

### `opening_balances_remove`

`DELETE /accounting/opening-balance/:entityId/:accountId` · **write** · destructive · confirm

```json
{ "entityId": 123, "accountId": "01979b94-..." }
```

***

## Entities & Workspace

### `financial_accounts_list`

`GET /user/workspaces/:workspaceId/entities` · **read** · idempotent

Connected bank and payment accounts with entity assignments.

```json
{ "workspaceId": "019e2df8-..." }
```

***

### `entities_search`

`GET /entity/search` · **read** · idempotent

Matches `entityName` and `workspaceName`. Optionally narrow by `workspaceIds` or `organizationId`.

```json
{ "search": "Acme", "organizationId": "01979b94-...", "limit": 10 }
```

***

### `entities_create`

`POST /entity` · **write** · non-destructive · confirm

Requires `UNLIMITED_ENTITIES` premium feature.

```json
{
  "payload": {
    "name": "Acme Consulting LLC",
    "workspaceId": "019e2df8-...",
    "bookkeepingStartDate": "2026-01-01"
  }
}
```

***

### `entities_update`

`PATCH /entity/:entityId` · **write** · destructive · confirm

```json
{
  "entityId": 12345,
  "payload": { "name": "Acme Consulting", "allowAITrainingOnTheirData": false }
}
```

***

### `entities_get_address`

`GET /entity/:entityId/address` · **read** · idempotent

```json
{ "entityId": 12345 }
```

***

### `entities_update_address`

`PUT /entity/address` · **write** · destructive · confirm

Replaces the full address.

```json
{
  "payload": {
    "entityId": 12345,
    "address": {
      "street": "123 Market St",
      "city": "San Francisco",
      "postalCode": "94105",
      "state": "CA"
    }
  }
}
```

***

### `entities_save_tax_locations`

`POST /entity/tax-location` · **write** · destructive · confirm

Replaces the saved tax-location set.

```json
{
  "payload": {
    "entityId": 12345,
    "taxLocations": [
      { "location": "CA", "start": "2026-01-01" }
    ]
  }
}
```

***

### `workspaces_list`

`GET /workspaces/list` · **read** · idempotent

Lists workspaces the authenticated credential can access. Organization membership scopes results but does not add unassigned workspaces.

```json
{
  "limit": 25,
  "includeEntities": true,
  "fields": ["id", "name", "plan", "organizationIds"]
}
```

***

### `workspaces_search`

`GET /workspaces/list` · **read** · idempotent

Search by workspace name or entity name when the user gives a name instead of a workspaceId. If multiple plausible rows, ask the user to choose using `name`, `id`, `plan`, `organizationIds`, `access`.

```json
{ "search": "Acme", "limit": 10, "fields": ["id", "name", "plan", "organizationIds"] }
```

***

### `workspaces_get`

`GET /workspaces/workspace/:workspaceId` · **read** · idempotent

Full workspace context: entities, members (id, name, email, role), and related metadata. Use before entity, account, report, or transaction operations.

```json
{ "workspaceId": "01979b94-..." }
```

***

### `workspace_context_get`

`GET /workspaces/workspace/:workspaceId/context` · **read** · idempotent

Compact bootstrap context in a single call: access metadata, reportable entities, available ledgers, and account catalog rows with entity names. Use after `workspaces_list` or `workspaces_search` before accounting, reporting, or transaction workflows.

```json
{ "workspaceId": "01979b94-..." }
```

***

## Client Onboarding

### `organization_clients_create`

`POST /organization-client/:organizationId` · **write** · non-destructive · confirm

Create a new client workspace under an accountant organization.

```json
{
  "organizationId": "01979b94-...",
  "payload": {
    "entity": {
      "name": "Acme Consulting LLC"
    }
  }
}
```

***

## Tasks

### `tasks_list`

`GET /tasks/:workspaceId` · **read** · idempotent

```json
{
  "workspaceId": "019e2df8-...",
  "fields": ["id", "title", "status", "priority", "dueDate"],
  "limit": 50
}
```

***

### `tasks_create`

`POST /tasks/:workspaceId` · **write** · non-destructive · confirm

Task type is fixed to `question`.

```json
{
  "workspaceId": "019e2df8-...",
  "payload": {
    "title": "Review Q4 financial statements",
    "description": "Please review and confirm the Q4 numbers."
  }
}
```

***

### `tasks_update`

`PATCH /tasks/:workspaceId/:taskId` · **write** · destructive · idempotent · confirm

All payload fields optional — only provided fields are changed.

```json
{
  "workspaceId": "019e2df8-...",
  "taskId": "01979b94-...",
  "payload": { "status": "done", "priority": "high" }
}
```

**`status`:** `todo` · `in_progress` · `blocked` · `done` · `cancelled` **`priority`:** `urgent` · `high` · `medium` · `low`

***

## Activity & Audit Trail

### `activity_list`

`GET /history/:workspaceId/history` · **read** · idempotent

Aggregated activity batches in a workspace. Use to understand recent bookkeeping changes, resolve batch details for `activity_details_get`, or choose a safe `activity_revert` target.

```json
{
  "workspaceId": "019e2df8-...",
  "limit": 25,
  "fields": ["date", "sourceType", "resourceType", "count"],
  "filters": {
    "resourceTypes": ["transaction"],
    "changedFields": ["categoryId"]
  }
}
```

***

### `activity_logs_list`

`GET /history/:workspaceId` · **read** · idempotent

Raw audit log rows with actor, resource, change type, and timestamp context. Use when aggregated activity is not enough to explain exactly what changed.

```json
{
  "workspaceId": "019e2df8-...",
  "limit": 25,
  "fields": ["createdAt", "resourceType", "changeType", "actor"],
  "filters": { "resourceTypes": ["transaction"] },
  "sort": { "field": "createdAt", "order": "DESC" }
}
```

***

### `activity_details_get`

`GET /history/:workspaceId/history/details` · **read** · idempotent

Drill-down rows for one aggregated activity batch. Use after `activity_list` to show affected resources before considering `activity_revert`.

```json
{
  "workspaceId": "019e2df8-...",
  "date": "2026-04-01T00:00:00.000Z",
  "sourceType": "transaction_bulk_update",
  "resourceType": "transaction",
  "changedFields": ["categoryId"],
  "fields": ["created_at", "resource_type", "resource_id"],
  "limit": 25
}
```

***

### `activity_revert`

`POST /history/:workspaceId/history/revert` · **write** · destructive · confirm

Revert a supported activity batch identified from `activity_details_get`. Not all batches are revertible — check details first.

```json
{
  "workspaceId": "019e2df8-...",
  "date": "2026-04-01T00:00:00.000Z",
  "sourceType": "transaction_bulk_update",
  "resourceType": "transaction",
  "fields": ["categoryId"],
  "changeTypes": ["UPDATE"]
}
```

***

## Typical flows

**Recategorize a transaction**

1. `transactions_find` { search/filters } → resolve id
2. `transactions_get` { transactionId } → confirm details
3. `categories_search` { search: "Travel" } → resolve categoryId
4. `transactions_update` { transactionId, payload: { categoryId } } → preview
5. `transactions_update` { ..., confirmationToken } → execute

**Match a transfer**

1. `transactions_find` → resolve origin id
2. `transactions_suggested_matches` { transactionId } → find target candidates
3. `transactions_match_transfer` { originTransactionId, payload: { targetTransactionId } } → preview
4. `transactions_match_transfer` { ..., confirmationToken } → execute

**Create a categorization rule**

1. `rules_groups_list` { workspaceId } → resolve groupId
2. `categories_search` → resolve categoryId
3. `rules_matching_transactions` with proposed conditions/actions → preview which transactions would match
4. `rules_create` { ..., payload } → preview
5. `rules_create` { ..., confirmationToken } → execute

**Run a P\&L**

1. `workspace_context_get` { workspaceId } → resolve entityId and ledgerId
2. `reports_profit_loss_get` { entityId, ledgerId, startDate, endDate, cycle: "month" }

**Undo recent bulk change**

1. `activity_list` { workspaceId, filters } → find the batch
2. `activity_details_get` → confirm scope
3. `activity_revert` → preview, then execute with token

***

{% hint style="info" %}
For a user-facing summary of available capabilities, see → [Available Tools](/ai/kick-mcp/available-tools.md).
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kick.co/ai/developer-tools/mcp/tool-reference.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
