Taxomat logo

Taxomat API

REST nad stejnými daty a scopy jako MCP. Bearer je OAuth access token nebo osobní klíč ze stránky AI a API.

Import

Export

Přihlášení

Hlavička Authorization Bearer. Osobní klíč začíná tm_ a platí 90 dní. Přihlášení přes OAuth si klient obnovuje sám; po 30 dnech v něm znovu Authenticate. Cíl je alias účtu z grantu, ne UUID.

Authorization: Bearer tm_…

Oprávnění a licence

Import JSON (scope imports:write) jde vždy, i bez licence a na Základním plánu. Export přehledu pozic (scope holdings:read) jen s Optimálním nebo Maximálním plánem — Základní nestačí. Na Optimálním je připojení časově omezené, na Maximálním bez limitu. Staré připojení s jen holdings:read import samo nedostane.

Import

Do jednoho účtu. Licence ani předplatné nejsou potřeba. Scope imports:write. Aliasy účtů na připojení čtěte GET /api/v1/accounts. JSON Schema je veřejné (GET /api/v1/imports/schema, bez tokenu). JSON obchody přes POST /imports. Výpisy brokerů (XTB, IB, …) stejné jako v Nahrání dat přes POST /import_files. Stav čtěte přes import_id.

GET /api/v1/accounts imports:write

Portfolia a účty zaškrtnuté u tohoto připojení. Strom portfolios → accounts, jen aliasy.

Požadavek

Bez těla. Žádné filtry.

Odpověď

JSON strom s aliasy. Stejné aliasy, které import očekává v account.alias.

Chyby

401 bez tokenu. 429 při limitu čtení — retry_after v těle a hlavičce Retry-After.

MCP: list_accounts (bez argumentů).

Ukázka:

curl -H "Authorization: Bearer tm_…" https://app.taxomat.cz/api/v1/accounts
GET /api/v1/imports/schema veřejné

Veřejné JSON Schema pro POST /api/v1/imports. Bez tokenu, bez scope.

Požadavek

Bez těla a bez Authorization.

Odpověď

JSON Schema.

Chyby

Žádné 401. Endpoint je otevřený.

MCP: describe_import_schema (v relaci MCP, stejné tělo).

Ukázka:

curl https://app.taxomat.cz/api/v1/imports/schema
POST /api/v1/imports imports:write

Asynchronní import JSON do jednoho účtu. Nic se nespočítá v requestu.

Požadavek

JSON tělo podle schématu. Povinné account.alias a broker (key, nebo name + address). Alespoň jeden řádek ve flows nebo corporate_actions.

Odpověď

202 { ok, import_id, filename, state, received_count }. Stejné tělo a 200 při opakování client_request_id.

Chyby

401 / 403 bez imports:write. 404 u cizího aliasu. 422 u neplatného JSON. 429 při více než 30 nahráních za hodinu — retry_after v těle a hlavičce Retry-After. Žádný dry_run.

MCP: import_flows (stejné tělo).

Stejný Bearer jako u ostatních endpointů. Cíl je jeden účet (alias z grantu). Commit je asynchronní. Žádný dry_run, žádné PDF ani XLSX na tomto endpointu.

unit_price je cena za kus včetně poplatku. Volitelné trade_fee je jen rozpad (celková komise v měně obchodu) — do ceny se nepřičítá. Nákup 10 ks po 180 USD + komise 5 USD → unit_price 180.5, trade_fee 5. Prodej 2 ks po 190 USD − komise 1 USD → unit_price 189.5, trade_fee 1.

{
  "account": { "alias": "account_1" },
  "broker": {
    "key": "ib",
    "name": "Interactive Brokers",
    "address": "91/92 N Wall Quay, North Wall, Dublin, Irsko"
  },
  "flows": [
    {
      "operation_type": "stock_buy",
      "date": "2026-01-15",
      "symbol": "AAPL",
      "isin": "US0378331005",
      "name": "Apple Inc.",
      "units": 10,
      "currency": "USD",
      "unit_price": 180.5,
      "trade_fee": 5.0
    }
  ]
}

Nahrání souboru import.json:

curl -X POST -H "Authorization: Bearer tm_…" -H "Content-Type: application/json" --data @import.json https://app.taxomat.cz/api/v1/imports
  • Cizí alias účtu nebo cizí import_id vrátí 404. UUID portfolia do těla nepatří.
  • Shorty, futures a forex v první vlně nejsou. Korporátní akce jdou do corporate_actions, ne do flows. Výpis brokera (XLSX, CSV, PDF, ZIP) sem nepatří — použijte POST /api/v1/import_files.
  • Nahrání se objeví v Nahrání dat se štítkem API, MCP, JSON, API vstup nebo MCP vstup. Mazání je jen tam, ne přes API.
POST /api/v1/import_files imports:write

Výpis brokera do jednoho účtu. Stejní importeři jako Nahrání dat (XTB, IB, Fio, Degiro, …).

Požadavek

multipart/form-data. Povinné alias (alias účtu z grantu) a file. ZIP se rozbalí.

Odpověď

202 { ok, import_id, state, imports[{ import_id, state, filename }] }.

Chyby

401 / 403 bez imports:write. 404 u cizího aliasu. 422 bez souboru nebo u prázdného / příliš velkého souboru. 429 při více než 10 souborech za minutu nebo 30 nahráních za hodinu — retry_after v těle a hlavičce Retry-After.

MCP: import_file (alias, filename, content_base64) nebo describe_file_import.

Stejný Bearer. Cíl je jeden účet. Zpracování je asynchronní, stejný probe jako na webu. JSON obchody nechte na POST /api/v1/imports.

Nahrání výpisu XTB:

curl -X POST -H "Authorization: Bearer tm_…" -F "alias=account_1" -F "[email protected]" https://app.taxomat.cz/api/v1/import_files
GET /api/v1/imports/:id imports:write

Stav nahrání, warningy a chyby. JSON i soubor brokera. Ne dump Flow.

Požadavek

id v URL je import_id z POST /imports nebo POST /import_files.

Odpověď

{ ok, import_id, filename, state, state_label, received_count, created_count, warnings[{ type, message, items }], errors }

Chyby

404 u cizího import_id. 403 bez oprávnění.

MCP: get_import.

import_id je UUID nahrání (handle na další dotaz, ne heslo). filename je název souboru. received_count = řádky vzaté ke zpracování (u JSON hned, u výpisu brokera až po importu). created_count = nově vytvořené pohyby; duplicita je 0. state: waiting_for_processing, processing, processed, processed_with_warnings (hotovo, část řádků přeskočena, typicky duplicity), empty_file, unknown_file / unknown_file_final, conflict_with_final_tax_return, brokers_limit_exceeded, subscription_expired, error.

Export

Přehled otevřených pozic, zhodnocení instrumentu a simulace prodeje u zaškrtnutých účtů. Jen s Optimálním nebo Maximálním plánem. Základní plán a účet bez licence export neudělají. Scope holdings:read.

GET /api/v1/holdings holdings:read

Otevřené pozice u zaškrtnutých účtů. Strom portfolios → accounts → stocks / bonds / crypto / options.

Požadavek

Bez těla. Žádné filtry.

Odpověď

JSON strom s aliasy. status ready používá stejnou bránu jako Základní přehled.

Chyby

401 bez tokenu. 403 bez holdings:read nebo bez Optimálního / Maximálního plánu. 429 při limitu čtení — retry_after v těle a hlavičce Retry-After.

MCP: list_holdings (bez argumentů).

Ukázka:

curl -H "Authorization: Bearer tm_…" https://app.taxomat.cz/api/v1/holdings

Ukázka holdings

{
  "portfolios": [
    {
      "alias": "portfolio_1",
      "accounts": [
        {
          "alias": "account_1",
          "status": "ready",
          "stocks": [
            {
              "isin": "US0378331005",
              "symbol": "AAPL",
              "units": 15,
              "average_price": 172.4,
              "currency": "USD",
              "last_price": 189.5,
              "exempt_units": 10,
              "next_exemption_on": "2027-06-01",
              "next_exemption_units": 5
            }
          ],
          "bonds": [],
          "crypto": [],
          "options": [
            {
              "name": "AAPL 20MAR26 180 C",
              "symbol": "AAPL",
              "option_type": "call",
              "strike": 180,
              "expires_on": "2026-03-20",
              "units": -2,
              "price": 640,
              "currency": "USD"
            }
          ]
        }
      ]
    }
  ]
}

status ready = stejná brána jako Základní přehled. tax_calculation_incomplete / no_data = pozice se nepočítají (nedokončené DP nebo žádná data).

Co pole znamenají

  • portfolios → accounts → stocks / bonds / crypto / options. portfolio je skupina účtů v Taxomatu (rodina, klient), ne účet u brokera. account je jeden investiční účet (IBKR, Fio…). alias je název, který uživatel nechal nebo anonymizoval — ne UUID.
  • stocks jsou otevřené akcie a ETF, ne obchody. bonds a crypto mají stejná pole. Tržní hodnota = units × last_price (last_price může chybět). isin u krypta často chybí.
  • options jsou jen otevřené kontrakty, ne fill. Stejný kontrakt (podklad, call/put, strike, expirace) se sčítá. units: long kladné, short záporné. name je původní označení z brokera. price je zbývající prémium (sloupec Cena v přehledu opcí), ne last z trhu.
  • exempt_units — kusy, které už splnily český 3letý časový test (osvobození, pokud by se dnes prodaly). next_exemption_on — datum dalšího osvobození (ISO YYYY-MM-DD). next_exemption_units — kusy, které se ten den osvobodí. next_* chybí, když je celá pozice už osvobozená.

Co API nevrací

  • Databázová UUID; jména portfolií a účtů jen když je necháte v aliasu
  • Historie obchodů
  • Daňové přiznání a e-mail
GET /api/v1/instrument_performance holdings:read

Zhodnocení (Celkem) jednoho instrumentu (akcie, ETF, dluhopis nebo krypto) podle ISIN na jednom účtu. Stejná čísla jako karta Zhodnocení v detailu.

Požadavek

Query: alias (povinné), isin (povinné), currency (volitelné — vynechat = měna instrumentu, nebo CZK).

Odpověď

JSON: invested_capital, market_value, průměry, realizovaný zisk (prodeje / dividendy / opce), nerealizovaný a celkový zisk. Bez kusů, osvobození a strategií.

Chyby

401 bez tokenu. 403 bez holdings:read nebo bez Optimálního / Maximálního. 404 u cizího aliasu nebo ISIN mimo účet. 422 u chybějícího alias/isin nebo nepovolené měny. 429 při limitu čtení — retry_after v těle a hlavičce Retry-After.

MCP: get_instrument_performance (alias, isin, volitelně currency). Nákladný — jeden ISIN na volání.

Ukázka:

curl -H "Authorization: Bearer tm_…" "https://app.taxomat.cz/api/v1/instrument_performance?alias=account_1&isin=US0378331005"

Instrument = akcie, ETF, dluhopis nebo krypto podle ISIN, ne název společnosti. Částky jsou v currency. Průměry na kus zůstávají v average_currency (měna instrumentu). Nevolat hromadně přes všechny řádky z list_holdings.

{
  "account": "account_1",
  "isin": "US0378331005",
  "symbol": "AAPL",
  "currency": "USD",
  "average_currency": "USD",
  "invested_capital": -1977,
  "market_value": 7774,
  "economic_average_price": -3.97,
  "economic_average_to_market_percent": null,
  "purchase_average_price": 9.57,
  "purchase_average_to_market_percent": 63.1,
  "realized": {
    "sales": 6744,
    "dividends": 0,
    "options": 0
  },
  "unrealized_profit": 3007,
  "unrealized_profit_percent": 63.1,
  "realized_profit": 6744,
  "realized_profit_percent": null,
  "total_profit": 9751
}
POST /api/v1/sale_simulation holdings:read

Simulace prodeje akcie/ETF na jednom účtu. Stejná čísla jako Simulace prodeje v trackeru. Nic nezapisuje.

Požadavek

JSON tělo: alias, isin, units, unit_price (povinné). date volitelné (ISO; default dnes; ne dřív než dnes).

Odpověď

JSON: sale_proceeds, prefer_exempted true/false, u každé metody taxable/exempt profit a units plus open_after_sale (průměr zbylých, kusy/hodnota, nejbližší časový test). Jen denní kurz.

Chyby

401 bez tokenu. 403 bez holdings:read nebo bez Optimálního / Maximálního. 404 u cizího aliasu nebo bez otevřených lotů. 422 u chybějících / neplatných vstupů. 429 při limitu čtení — retry_after v těle a hlavičce Retry-After.

MCP: simulate_sale (alias, isin, units, unit_price, volitelně date). Nákladný — jeden scénář na volání.

Ukázka:

curl -X POST -H "Authorization: Bearer tm_…" -H "Content-Type: application/json" \
  -d '{"alias":"account_1","isin":"US0378331005","units":76,"unit_price":15.61,"date":"2027-10-09"}' \
  https://app.taxomat.cz/api/v1/sale_simulation

Jen denní kurz. Obě varianty Upřednostnit osvobozené. Bez doporučené metody a bez rozpadu lotů. Nezapisuje obchod.

{
  "account": "account_1",
  "isin": "US0378331005",
  "symbol": "SOFI.US",
  "date": "2027-10-09",
  "units": 76,
  "unit_price": 15.61,
  "currency": "USD",
  "sale_proceeds": 1186.36,
  "exchange_method": "daily_rates",
  "prefer_exempted": {
    "true": {
      "methods": {
        "fifo": {
          "taxable_profit": 0,
          "taxable_units": 0,
          "exempt_profit": 13053,
          "exempt_units": 76,
          "open_after_sale": {
            "average_price": 7.71,
            "exempt_units": 400,
            "exempt_value": 136188,
            "taxable_units": 22,
            "taxable_value": 7490,
            "next_time_test_on": "2029-05-07",
            "next_time_test_units": 22
          }
        }
      }
    },
    "false": { "methods": {} }
  }
}