--- openapi: 3.0.3 info: title: Sure API version: v1 description: OpenAPI documentation generated from executable request specs. servers: - url: https://app.sure.am description: Production - url: http://localhost:3000 description: Local development components: securitySchemes: apiKeyAuth: type: apiKey name: X-Api-Key in: header description: API key for authentication. Generate one from your account settings. schemas: Pagination: type: object required: - page - per_page - total_count - total_pages properties: page: type: integer minimum: 1 per_page: type: integer minimum: 1 total_count: type: integer minimum: 0 total_pages: type: integer minimum: 0 ErrorResponse: type: object required: - error properties: error: type: string message: type: string nullable: true details: oneOf: - type: array items: type: string - type: object nullable: true errors: type: array items: type: string nullable: true description: Validation error messages (alternative to details used by trades, valuations, etc.) ToolCall: type: object required: - id - function_name - function_arguments - created_at properties: id: type: string format: uuid function_name: type: string function_arguments: type: object additionalProperties: true function_result: type: object additionalProperties: true nullable: true created_at: type: string format: date-time Message: type: object required: - id - type - role - content - created_at - updated_at properties: id: type: string format: uuid type: type: string enum: - user_message - assistant_message role: type: string enum: - user - assistant content: type: string model: type: string nullable: true created_at: type: string format: date-time updated_at: type: string format: date-time tool_calls: type: array items: "$ref": "#/components/schemas/ToolCall" nullable: true MessageResponse: allOf: - "$ref": "#/components/schemas/Message" - type: object required: - chat_id properties: chat_id: type: string format: uuid ai_response_status: type: string enum: - pending - complete - failed nullable: true ai_response_message: type: string nullable: true ChatResource: type: object required: - id - title - created_at - updated_at properties: id: type: string format: uuid title: type: string error: type: string nullable: true created_at: type: string format: date-time updated_at: type: string format: date-time ChatSummary: allOf: - "$ref": "#/components/schemas/ChatResource" - type: object required: - message_count properties: message_count: type: integer minimum: 0 last_message_at: type: string format: date-time nullable: true ChatDetail: allOf: - "$ref": "#/components/schemas/ChatResource" - type: object required: - messages properties: messages: type: array items: "$ref": "#/components/schemas/Message" pagination: "$ref": "#/components/schemas/Pagination" nullable: true ChatCollection: type: object required: - chats - pagination properties: chats: type: array items: "$ref": "#/components/schemas/ChatSummary" pagination: "$ref": "#/components/schemas/Pagination" RetryResponse: type: object required: - message - message_id properties: message: type: string message_id: type: string format: uuid Account: type: object required: - id - name - account_type properties: id: type: string format: uuid name: type: string account_type: type: string AccountDetail: type: object required: - id - name - balance - currency - classification - account_type properties: id: type: string format: uuid name: type: string balance: type: string currency: type: string classification: type: string account_type: type: string AccountCollection: type: object required: - accounts - pagination properties: accounts: type: array items: "$ref": "#/components/schemas/AccountDetail" pagination: "$ref": "#/components/schemas/Pagination" Category: type: object required: - id - name - classification - color - icon properties: id: type: string format: uuid name: type: string classification: type: string color: type: string icon: type: string CategoryParent: type: object required: - id - name properties: id: type: string format: uuid name: type: string CategoryDetail: type: object required: - id - name - classification - color - icon - subcategories_count - created_at - updated_at properties: id: type: string format: uuid name: type: string classification: type: string enum: - income - expense color: type: string icon: type: string parent: "$ref": "#/components/schemas/CategoryParent" nullable: true subcategories_count: type: integer minimum: 0 created_at: type: string format: date-time updated_at: type: string format: date-time CategoryCollection: type: object required: - categories - pagination properties: categories: type: array items: "$ref": "#/components/schemas/CategoryDetail" pagination: "$ref": "#/components/schemas/Pagination" Merchant: type: object required: - id - name properties: id: type: string format: uuid name: type: string Tag: type: object required: - id - name - color properties: id: type: string format: uuid name: type: string color: type: string TagDetail: type: object required: - id - name - color - created_at - updated_at properties: id: type: string format: uuid name: type: string color: type: string created_at: type: string format: date-time updated_at: type: string format: date-time TagCollection: type: array items: "$ref": "#/components/schemas/TagDetail" Transfer: type: object required: - id - amount - currency properties: id: type: string format: uuid amount: type: string currency: type: string other_account: "$ref": "#/components/schemas/Account" nullable: true Transaction: type: object required: - id - date - amount - currency - name - classification - account - tags - created_at - updated_at properties: id: type: string format: uuid date: type: string format: date amount: type: string currency: type: string name: type: string notes: type: string nullable: true classification: type: string account: "$ref": "#/components/schemas/Account" category: "$ref": "#/components/schemas/Category" nullable: true merchant: "$ref": "#/components/schemas/Merchant" nullable: true tags: type: array items: "$ref": "#/components/schemas/Tag" transfer: "$ref": "#/components/schemas/Transfer" nullable: true created_at: type: string format: date-time updated_at: type: string format: date-time TransactionCollection: type: object required: - transactions - pagination properties: transactions: type: array items: "$ref": "#/components/schemas/Transaction" pagination: "$ref": "#/components/schemas/Pagination" Valuation: type: object required: - id - date - amount - currency - kind - account - created_at - updated_at properties: id: type: string format: uuid date: type: string format: date amount: type: string currency: type: string notes: type: string nullable: true kind: type: string account: "$ref": "#/components/schemas/Account" created_at: type: string format: date-time updated_at: type: string format: date-time DeleteResponse: type: object required: - message properties: message: type: string ImportConfiguration: type: object properties: date_col_label: type: string nullable: true amount_col_label: type: string nullable: true name_col_label: type: string nullable: true category_col_label: type: string nullable: true tags_col_label: type: string nullable: true notes_col_label: type: string nullable: true account_col_label: type: string nullable: true date_format: type: string nullable: true number_format: type: string nullable: true signage_convention: type: string nullable: true ImportStats: type: object properties: rows_count: type: integer minimum: 0 valid_rows_count: type: integer minimum: 0 nullable: true ImportSummary: type: object required: - id - type - status - created_at - updated_at properties: id: type: string format: uuid type: type: string enum: - TransactionImport - TradeImport - AccountImport - MintImport - CategoryImport - RuleImport status: type: string enum: - pending - complete - importing - reverting - revert_failed - failed created_at: type: string format: date-time updated_at: type: string format: date-time account_id: type: string format: uuid nullable: true rows_count: type: integer minimum: 0 error: type: string nullable: true ImportDetail: type: object required: - id - type - status - created_at - updated_at properties: id: type: string format: uuid type: type: string enum: - TransactionImport - TradeImport - AccountImport - MintImport - CategoryImport - RuleImport status: type: string enum: - pending - complete - importing - reverting - revert_failed - failed created_at: type: string format: date-time updated_at: type: string format: date-time account_id: type: string format: uuid nullable: true error: type: string nullable: true configuration: "$ref": "#/components/schemas/ImportConfiguration" stats: "$ref": "#/components/schemas/ImportStats" ImportCollection: type: object required: - data - meta properties: data: type: array items: "$ref": "#/components/schemas/ImportSummary" meta: type: object required: - current_page - total_pages - total_count - per_page properties: current_page: type: integer minimum: 1 next_page: type: integer nullable: true prev_page: type: integer nullable: true total_pages: type: integer minimum: 0 total_count: type: integer minimum: 0 per_page: type: integer minimum: 1 ImportResponse: type: object required: - data properties: data: "$ref": "#/components/schemas/ImportDetail" Trade: type: object required: - id - date - amount - currency - name - qty - price - account - created_at - updated_at properties: id: type: string format: uuid date: type: string format: date amount: type: string currency: type: string name: type: string notes: type: string nullable: true qty: type: string price: type: string investment_activity_label: type: string nullable: true account: "$ref": "#/components/schemas/Account" security: type: object nullable: true properties: id: type: string format: uuid ticker: type: string name: type: string nullable: true category: type: object nullable: true properties: id: type: string format: uuid name: type: string created_at: type: string format: date-time updated_at: type: string format: date-time TradeCollection: type: object required: - trades - pagination properties: trades: type: array items: "$ref": "#/components/schemas/Trade" pagination: "$ref": "#/components/schemas/Pagination" Holding: type: object required: - id - date - qty - price - amount - currency - account - security - created_at - updated_at properties: id: type: string format: uuid date: type: string format: date qty: type: string description: Quantity as string (JSON number or string from API) price: type: string description: Price as string (JSON number or string from API) amount: type: string currency: type: string cost_basis_source: type: string nullable: true account: "$ref": "#/components/schemas/Account" security: type: object required: - id - ticker - name properties: id: type: string format: uuid ticker: type: string name: type: string nullable: true avg_cost: type: string nullable: true created_at: type: string format: date-time updated_at: type: string format: date-time HoldingCollection: type: object required: - holdings - pagination properties: holdings: type: array items: "$ref": "#/components/schemas/Holding" pagination: "$ref": "#/components/schemas/Pagination" paths: "/api/v1/accounts": get: summary: List accounts tags: - Accounts security: - apiKeyAuth: [] parameters: - name: page in: query required: false description: 'Page number (default: 1)' schema: type: integer - name: per_page in: query required: false description: 'Items per page (default: 25, max: 100)' schema: type: integer responses: '200': description: accounts paginated content: application/json: schema: "$ref": "#/components/schemas/AccountCollection" "/api/v1/categories": get: summary: List categories tags: - Categories security: - apiKeyAuth: [] parameters: - name: page in: query required: false description: 'Page number (default: 1)' schema: type: integer - name: per_page in: query required: false description: 'Items per page (default: 25, max: 100)' schema: type: integer - name: classification in: query required: false description: Filter by classification (income or expense) schema: type: string enum: - income - expense - name: roots_only in: query required: false description: Return only root categories (no parent) schema: type: boolean - name: parent_id in: query required: false description: Filter by parent category ID schema: type: string format: uuid responses: '200': description: categories filtered by parent content: application/json: schema: "$ref": "#/components/schemas/CategoryCollection" "/api/v1/categories/{id}": parameters: - name: id in: path required: true description: Category ID schema: type: string get: summary: Retrieve a category tags: - Categories security: - apiKeyAuth: [] responses: '200': description: subcategory retrieved with parent content: application/json: schema: "$ref": "#/components/schemas/CategoryDetail" '404': description: category not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/chats": get: summary: List chats tags: - Chats security: - apiKeyAuth: [] responses: '200': description: chats listed content: application/json: schema: "$ref": "#/components/schemas/ChatCollection" '403': description: AI features disabled content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create chat tags: - Chats security: - apiKeyAuth: [] parameters: [] responses: '201': description: chat created content: application/json: schema: "$ref": "#/components/schemas/ChatDetail" '422': description: validation error content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: title: type: string example: Monthly budget review message: type: string description: Optional initial message in the chat model: type: string description: Optional OpenAI model identifier required: - title required: true "/api/v1/chats/{id}": parameters: - name: id in: path required: true description: Chat ID schema: type: string get: summary: Retrieve a chat tags: - Chats security: - apiKeyAuth: [] responses: '200': description: chat retrieved content: application/json: schema: "$ref": "#/components/schemas/ChatDetail" '404': description: chat not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a chat tags: - Chats security: - apiKeyAuth: [] parameters: [] responses: '200': description: chat updated content: application/json: schema: "$ref": "#/components/schemas/ChatDetail" '404': description: chat not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '422': description: validation error content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: title: type: string example: Updated chat title required: true delete: summary: Delete a chat tags: - Chats security: - apiKeyAuth: [] responses: '204': description: chat deleted '404': description: chat not found "/api/v1/chats/{chat_id}/messages": parameters: - name: chat_id in: path required: true description: Chat ID schema: type: string post: summary: Create a message tags: - Chat Messages security: - apiKeyAuth: [] parameters: [] responses: '201': description: message created content: application/json: schema: "$ref": "#/components/schemas/MessageResponse" '404': description: chat not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '422': description: validation error content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: content: type: string model: type: string required: - content required: true "/api/v1/chats/{chat_id}/messages/retry": parameters: - name: chat_id in: path required: true description: Chat ID schema: type: string post: summary: Retry the last assistant response tags: - Chat Messages security: - apiKeyAuth: [] responses: '202': description: retry started content: application/json: schema: "$ref": "#/components/schemas/RetryResponse" '404': description: chat not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '422': description: no assistant message available content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/holdings": get: summary: List holdings tags: - Holdings security: - apiKeyAuth: [] parameters: - name: page in: query required: false description: 'Page number (default: 1)' schema: type: integer - name: per_page in: query required: false description: 'Items per page (default: 25, max: 100)' schema: type: integer - name: account_id in: query required: false description: Filter by account ID schema: type: string - name: account_ids in: query required: false description: Filter by multiple account IDs schema: type: array items: type: string - name: date in: query required: false description: Filter by exact date schema: type: string format: date - name: start_date in: query required: false description: Filter holdings from this date (inclusive) schema: type: string format: date - name: end_date in: query required: false description: Filter holdings until this date (inclusive) schema: type: string format: date - name: security_id in: query required: false description: Filter by security ID schema: type: string responses: '200': description: holdings paginated content: application/json: schema: "$ref": "#/components/schemas/HoldingCollection" '401': description: unauthorized content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '422': description: invalid date filter content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/holdings/{id}": parameters: - name: id in: path description: Holding ID required: true schema: type: string get: summary: Retrieve holding tags: - Holdings security: - apiKeyAuth: [] responses: '200': description: holding retrieved content: application/json: schema: "$ref": "#/components/schemas/Holding" '401': description: unauthorized content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '404': description: holding not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/imports": get: summary: List imports description: List all imports for the user's family with pagination and filtering. tags: - Imports security: - apiKeyAuth: [] parameters: - name: page in: query required: false description: 'Page number (default: 1)' schema: type: integer - name: per_page in: query required: false description: 'Items per page (default: 25, max: 100)' schema: type: integer - name: status in: query required: false description: Filter by status schema: type: string enum: - pending - complete - importing - reverting - revert_failed - failed - name: type in: query required: false description: Filter by import type schema: type: string enum: - TransactionImport - TradeImport - AccountImport - MintImport - CategoryImport - RuleImport responses: '200': description: imports filtered by type content: application/json: schema: "$ref": "#/components/schemas/ImportCollection" post: summary: Create import description: Create a new import from raw CSV content. tags: - Imports security: - apiKeyAuth: [] parameters: [] responses: '201': description: import created content: application/json: schema: "$ref": "#/components/schemas/ImportResponse" '422': description: validation error - file too large content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: raw_file_content: type: string description: The raw CSV content as a string type: type: string enum: - TransactionImport - TradeImport - AccountImport - MintImport - CategoryImport - RuleImport description: Import type (defaults to TransactionImport) account_id: type: string format: uuid description: Account ID to import into publish: type: string description: Set to "true" to automatically queue for processing if configuration is valid date_col_label: type: string description: Header name for the date column amount_col_label: type: string description: Header name for the amount column name_col_label: type: string description: Header name for the transaction name column category_col_label: type: string description: Header name for the category column tags_col_label: type: string description: Header name for the tags column notes_col_label: type: string description: Header name for the notes column date_format: type: string description: Date format pattern (e.g., "%m/%d/%Y") number_format: type: string enum: - '1,234.56' - 1.234,56 - 1 234,56 - '1,234' description: Number format for parsing amounts signage_convention: type: string enum: - inflows_positive - inflows_negative description: How to interpret positive/negative amounts col_sep: type: string enum: - "," - ";" description: Column separator required: true "/api/v1/imports/{id}": parameters: - name: id in: path required: true description: Import ID schema: type: string get: summary: Retrieve an import description: Retrieve detailed information about a specific import, including configuration and row statistics. tags: - Imports security: - apiKeyAuth: [] responses: '200': description: import retrieved content: application/json: schema: "$ref": "#/components/schemas/ImportResponse" '404': description: import not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/tags": get: summary: List tags tags: - Tags security: - apiKeyAuth: [] responses: '200': description: tags listed content: application/json: schema: "$ref": "#/components/schemas/TagCollection" post: summary: Create tag tags: - Tags security: - apiKeyAuth: [] parameters: [] responses: '201': description: tag created with auto-assigned color content: application/json: schema: "$ref": "#/components/schemas/TagDetail" '422': description: validation error - missing name content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: tag: type: object properties: name: type: string description: Tag name (required) color: type: string description: Hex color code (optional, auto-assigned if not provided) required: - name required: - tag required: true "/api/v1/tags/{id}": parameters: - name: id in: path required: true description: Tag ID schema: type: string get: summary: Retrieve a tag tags: - Tags security: - apiKeyAuth: [] responses: '200': description: tag retrieved content: application/json: schema: "$ref": "#/components/schemas/TagDetail" '404': description: tag not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a tag tags: - Tags security: - apiKeyAuth: [] parameters: [] responses: '200': description: tag updated content: application/json: schema: "$ref": "#/components/schemas/TagDetail" '404': description: tag not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: tag: type: object properties: name: type: string color: type: string required: true delete: summary: Delete a tag tags: - Tags security: - apiKeyAuth: [] responses: '204': description: tag deleted '404': description: tag not found "/api/v1/trades": get: summary: List trades tags: - Trades security: - apiKeyAuth: [] parameters: - name: page in: query required: false description: 'Page number (default: 1)' schema: type: integer - name: per_page in: query required: false description: 'Items per page (default: 25, max: 100)' schema: type: integer - name: account_id in: query required: false description: Filter by account ID schema: type: string - name: account_ids in: query required: false description: Filter by multiple account IDs schema: type: array items: type: string - name: start_date in: query required: false description: Filter trades from this date (inclusive) schema: type: string format: date - name: end_date in: query required: false description: Filter trades until this date (inclusive) schema: type: string format: date responses: '200': description: trades paginated content: application/json: schema: "$ref": "#/components/schemas/TradeCollection" '401': description: unauthorized content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '422': description: invalid date filter content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" post: summary: Create trade tags: - Trades security: - apiKeyAuth: [] parameters: [] responses: '201': description: trade created content: application/json: schema: "$ref": "#/components/schemas/Trade" '422': description: validation error - missing security identifier content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '404': description: account not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: trade: type: object properties: account_id: type: string format: uuid description: Account ID (required) date: type: string format: date description: Trade date (required) qty: type: number description: Quantity (required) price: type: number description: Price (required) type: type: string enum: - buy - sell description: Trade type (required) security_id: type: string format: uuid description: Security ID (one of security_id, ticker, manual_ticker required) ticker: type: string description: Ticker symbol manual_ticker: type: string description: Manual ticker for offline securities currency: type: string description: Currency (defaults to account currency) investment_activity_label: type: string description: Activity label (e.g. Buy, Sell) category_id: type: string format: uuid description: Category ID required: - account_id - date - qty - price - type required: - trade required: true "/api/v1/trades/{id}": parameters: - name: id in: path description: Trade ID required: true schema: type: string get: summary: Retrieve trade tags: - Trades security: - apiKeyAuth: [] responses: '200': description: trade retrieved content: application/json: schema: "$ref": "#/components/schemas/Trade" '401': description: unauthorized content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '404': description: trade not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update trade tags: - Trades security: - apiKeyAuth: [] responses: '200': description: trade updated content: application/json: schema: "$ref": "#/components/schemas/Trade" '404': description: trade not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '422': description: validation error content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: trade: type: object description: Flat params; controller builds internal structure. When qty/price are updated, type or nature controls sign; if omitted, existing trade direction is preserved. properties: date: type: string format: date name: type: string amount: type: number currency: type: string notes: type: string nature: type: string enum: - inflow - outflow type: type: string enum: - buy - sell description: Determines sign when qty/price are updated. qty: type: number price: type: number investment_activity_label: type: string category_id: type: string format: uuid required: true delete: summary: Delete trade tags: - Trades security: - apiKeyAuth: [] responses: '200': description: trade deleted content: application/json: schema: "$ref": "#/components/schemas/DeleteResponse" '404': description: trade not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/transactions": get: summary: List transactions tags: - Transactions security: - apiKeyAuth: [] parameters: - name: page in: query required: false description: 'Page number (default: 1)' schema: type: integer - name: per_page in: query required: false description: 'Items per page (default: 25, max: 100)' schema: type: integer - name: account_id in: query required: false description: Filter by account ID schema: type: string - name: category_id in: query required: false description: Filter by category ID schema: type: string - name: merchant_id in: query required: false description: Filter by merchant ID schema: type: string - name: start_date in: query required: false description: Filter transactions from this date schema: type: string format: date - name: end_date in: query required: false description: Filter transactions until this date schema: type: string format: date - name: min_amount in: query required: false description: Filter by minimum amount schema: type: number - name: max_amount in: query required: false description: Filter by maximum amount schema: type: number - name: type in: query required: false description: Filter by transaction type schema: type: string enum: - income - expense - name: search in: query required: false description: Search by name, notes, or merchant name schema: type: string - name: account_ids in: query required: false description: Filter by multiple account IDs schema: type: array items: type: string - name: category_ids in: query required: false description: Filter by multiple category IDs schema: type: array items: type: string - name: merchant_ids in: query required: false description: Filter by multiple merchant IDs schema: type: array items: type: string - name: tag_ids in: query required: false description: Filter by tag IDs schema: type: array items: type: string responses: '200': description: transactions filtered by date range content: application/json: schema: "$ref": "#/components/schemas/TransactionCollection" post: summary: Create transaction tags: - Transactions security: - apiKeyAuth: [] parameters: [] responses: '201': description: transaction created content: application/json: schema: "$ref": "#/components/schemas/Transaction" '422': description: validation error - missing required fields content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: transaction: type: object properties: account_id: type: string format: uuid description: Account ID (required) date: type: string format: date description: Transaction date amount: type: number description: Transaction amount name: type: string description: Transaction name/description description: type: string description: Alternative to name field notes: type: string description: Additional notes currency: type: string description: Currency code (defaults to family currency) category_id: type: string format: uuid description: Category ID merchant_id: type: string format: uuid description: Merchant ID nature: type: string enum: - income - expense - inflow - outflow description: Transaction nature (determines sign) tag_ids: type: array items: type: string format: uuid description: Array of tag IDs required: - account_id - date - amount - name required: - transaction required: true "/api/v1/transactions/{id}": parameters: - name: id in: path required: true description: Transaction ID schema: type: string get: summary: Retrieve a transaction tags: - Transactions security: - apiKeyAuth: [] responses: '200': description: transaction retrieved content: application/json: schema: "$ref": "#/components/schemas/Transaction" '404': description: transaction not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a transaction tags: - Transactions security: - apiKeyAuth: [] parameters: [] responses: '200': description: transaction updated content: application/json: schema: "$ref": "#/components/schemas/Transaction" '404': description: transaction not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: transaction: type: object properties: date: type: string format: date amount: type: number name: type: string description: type: string description: Alternative to name field notes: type: string currency: type: string description: Currency code category_id: type: string format: uuid merchant_id: type: string format: uuid nature: type: string enum: - income - expense - inflow - outflow tag_ids: type: array items: type: string format: uuid required: true delete: summary: Delete a transaction tags: - Transactions security: - apiKeyAuth: [] responses: '200': description: transaction deleted content: application/json: schema: "$ref": "#/components/schemas/DeleteResponse" '404': description: transaction not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" "/api/v1/valuations": post: summary: Create valuation tags: - Valuations security: - apiKeyAuth: [] parameters: - name: Authorization in: header required: true schema: type: string description: Bearer token with write scope responses: '201': description: valuation created content: application/json: schema: "$ref": "#/components/schemas/Valuation" '422': description: validation error - missing date content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '404': description: account not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: valuation: type: object properties: account_id: type: string format: uuid description: Account ID (required) amount: type: number description: Valuation amount (required) date: type: string format: date description: Valuation date (required) notes: type: string description: Additional notes required: - account_id - amount - date required: - valuation required: true "/api/v1/valuations/{id}": parameters: - name: Authorization in: header required: true schema: type: string description: Bearer token - name: id in: path required: true description: Valuation ID (entry ID) schema: type: string get: summary: Retrieve a valuation tags: - Valuations security: - apiKeyAuth: [] responses: '200': description: valuation retrieved content: application/json: schema: "$ref": "#/components/schemas/Valuation" '404': description: valuation not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" patch: summary: Update a valuation tags: - Valuations security: - apiKeyAuth: [] parameters: [] responses: '200': description: valuation updated with amount and date content: application/json: schema: "$ref": "#/components/schemas/Valuation" '422': description: validation error - only one of amount/date provided content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" '404': description: valuation not found content: application/json: schema: "$ref": "#/components/schemas/ErrorResponse" requestBody: content: application/json: schema: type: object properties: valuation: type: object properties: amount: type: number description: New valuation amount (must provide with date) date: type: string format: date description: New valuation date (must provide with amount) notes: type: string description: Additional notes required: true