> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trycherry.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# End-to-end walkthrough

> Push a transaction, watch Cherry categorize it, and pull it back on your P&L.

This guide runs the full pipeline once, so the claim on the homepage ("Cherry categorizes, books, and folds pushed transactions into your statements") becomes something you've watched happen. You will:

1. Create a manual bank account.
2. Push one transaction into it.
3. Read the transaction back with its categorization.
4. Read the resulting P\&L line.

You need a `write` API key. See [Authentication](/authentication) if you don't have one yet.

## 1. Create a bank account

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.trycherry.ai/v1/bank-accounts \
    -H "Authorization: Bearer ck_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "institutionName": "Chase",
      "accounts": [
        {
          "externalId": "chk-1",
          "name": "Business Checking",
          "kind": "checking",
          "currency": "USD",
          "openingBalance": 10000.00,
          "openingBalanceDate": "2026-01-01"
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.trycherry.ai/v1/bank-accounts", {
    method: "POST",
    headers: {
      Authorization: "Bearer ck_live_your_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      institutionName: "Chase",
      accounts: [
        {
          externalId: "chk-1",
          name: "Business Checking",
          kind: "checking",
          currency: "USD",
          openingBalance: 10000.0,
          openingBalanceDate: "2026-01-01",
        },
      ],
    }),
  });
  const { data } = await res.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.post(
      "https://api.trycherry.ai/v1/bank-accounts",
      headers={"Authorization": "Bearer ck_live_your_key_here"},
      json={
          "institutionName": "Chase",
          "accounts": [
              {
                  "externalId": "chk-1",
                  "name": "Business Checking",
                  "kind": "checking",
                  "currency": "USD",
                  "openingBalance": 10000.00,
                  "openingBalanceDate": "2026-01-01",
              }
          ],
      },
  )
  data = res.json()["data"]
  ```
</CodeGroup>

The response confirms the account and whether it was auto-mapped to a ledger account. Re-posting the same institution is safe: `externalId` keeps it idempotent.

## 2. Push a transaction

Send one Figma subscription charge on that account.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.trycherry.ai/v1/transactions \
    -H "Authorization: Bearer ck_live_your_key_here" \
    -H "Content-Type: application/json" \
    -d '{
      "institutionName": "Chase",
      "transactions": [
        {
          "accountExternalId": "chk-1",
          "id": "txn-e2e-001",
          "date": "2026-08-15",
          "amount": 49.99,
          "description": "Figma subscription",
          "merchant": "Figma"
        }
      ]
    }'
  ```

  ```javascript JavaScript theme={null}
  const res = await fetch("https://api.trycherry.ai/v1/transactions", {
    method: "POST",
    headers: {
      Authorization: "Bearer ck_live_your_key_here",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      institutionName: "Chase",
      transactions: [
        {
          accountExternalId: "chk-1",
          id: "txn-e2e-001",
          date: "2026-08-15",
          amount: 49.99,
          description: "Figma subscription",
          merchant: "Figma",
        },
      ],
    }),
  });
  const { data } = await res.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.post(
      "https://api.trycherry.ai/v1/transactions",
      headers={"Authorization": "Bearer ck_live_your_key_here"},
      json={
          "institutionName": "Chase",
          "transactions": [
              {
                  "accountExternalId": "chk-1",
                  "id": "txn-e2e-001",
                  "date": "2026-08-15",
                  "amount": 49.99,
                  "description": "Figma subscription",
                  "merchant": "Figma",
              }
          ],
      },
  )
  data = res.json()["data"]
  ```
</CodeGroup>

```json theme={null}
{ "data": { "received": 1, "imported": 1, "deduplicated": 0 } }
```

Amount is `49.99`, not `-49.99`: positive is money out. See [Conventions](/conventions#amount-sign-convention).

Re-running this exact call is a no-op. `txn-e2e-001` is your stable id, so Cherry will match and dedupe.

## 3. Read it back, categorized

Categorization runs asynchronously and usually completes within a minute or two. Poll the transaction until `category` is populated.

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.trycherry.ai/v1/transactions?from=2026-08-15&to=2026-08-15" \
    -H "Authorization: Bearer ck_live_your_key_here"
  ```

  ```javascript JavaScript theme={null}
  const url = new URL("https://api.trycherry.ai/v1/transactions");
  url.searchParams.set("from", "2026-08-15");
  url.searchParams.set("to", "2026-08-15");

  const res = await fetch(url, {
    headers: { Authorization: "Bearer ck_live_your_key_here" },
  });
  const { data } = await res.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.get(
      "https://api.trycherry.ai/v1/transactions",
      params={"from": "2026-08-15", "to": "2026-08-15"},
      headers={"Authorization": "Bearer ck_live_your_key_here"},
  )
  data = res.json()["data"]
  ```
</CodeGroup>

```json theme={null}
{
  "data": [
    {
      "id": "manual:chase:chk-1:txn-e2e-001",
      "date": "2026-08-15",
      "amount": 49.99,
      "description": "Figma subscription",
      "merchant": "Figma",
      "category": "6110",
      "categoryName": "Software & Subscriptions",
      "needsReview": false
    }
  ],
  "meta": { "pagination": { "limit": 50, "offset": 0, "nextOffset": null } }
}
```

If the category is wrong, PATCH it. Cherry remembers the correction for future transactions from the same merchant:

```bash theme={null}
curl -X PATCH https://api.trycherry.ai/v1/transactions/manual:chase:chk-1:txn-e2e-001 \
  -H "Authorization: Bearer ck_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "category": "6120" }'
```

## 4. See it on the P\&L

The same categorization drives your statements. Pull August's profit and loss:

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://api.trycherry.ai/v1/reports/statements/profit_and_loss?from=2026-08-01&to=2026-08-31" \
    -H "Authorization: Bearer ck_live_your_key_here"
  ```

  ```javascript JavaScript theme={null}
  const url = new URL("https://api.trycherry.ai/v1/reports/statements/profit_and_loss");
  url.searchParams.set("from", "2026-08-01");
  url.searchParams.set("to", "2026-08-31");

  const res = await fetch(url, {
    headers: { Authorization: "Bearer ck_live_your_key_here" },
  });
  const statement = await res.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.get(
      "https://api.trycherry.ai/v1/reports/statements/profit_and_loss",
      params={"from": "2026-08-01", "to": "2026-08-31"},
      headers={"Authorization": "Bearer ck_live_your_key_here"},
  )
  statement = res.json()
  ```
</CodeGroup>

The `Software & Subscriptions` line under expenses includes your \$49.99 charge. The figures here come from the same generator the Cherry app uses, so what you see in the API matches the product exactly.

## What you just did

* Cherry took a raw bank transaction and mapped it to a ledger account (`6110`).
* It booked a journal entry against the checking account you created in step 1.
* The entry rolled into the P\&L for August without any extra call.

## Where to go next

* [Push your own transactions](/guides/manual-banks) covers batching, large imports, and the full idempotency rules.
* [Connect an agent over MCP](/guides/mcp) exposes the same pipeline as tools for Claude or ChatGPT.
* The **API Reference** tab has every endpoint used above with the full request and response schemas.
