{"openapi":"3.1.0","info":{"title":"POST /api/v1/transactions/batch/mark-reviewed-by-filter","version":"1.0.0","description":"Mark machine-categorized transactions reviewed by filter"},"servers":[{"url":"https://api.ondayzero.com","description":"Production"}],"paths":{"/api/v1/transactions/batch/mark-reviewed-by-filter":{"post":{"tags":["transactions"],"summary":"Mark machine-categorized transactions reviewed by filter","description":"Mark every unreviewed transaction a machine categorized (bank rule, counterparty rule, merchant pattern, history, AI) that matches a filter as reviewed: by who categorized it, a confidence floor, counterparties, an amount ceiling or a date range. Rows a person categorized, transfers and uncategorized rows are never selected. `dry_run` returns the count and a sample. The ids-based `PATCH /batch/review-status` is unchanged.","operationId":"mark_transactions_reviewed_by_filter","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}},{"name":"x-business-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Business-Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransactionReviewByFilterRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope_TransactionReviewByFilterResponse_"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"example":{"error":"validation_error","message":"Validation failed: due_date: Input should be a valid date","errors":{"due_date":"Input should be a valid date"},"code":"GEN_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Missing or expired token, an MCP OAuth token used against the REST API, or no access to this business","content":{"application/json":{"example":{"error":"unauthorized","message":"Authentication required","code":"AUTH_001","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"example":{"error":"forbidden","message":"You don't have permission to access this resource","code":"AUTH_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"},"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"error":"validation_error","message":"Validation failed: amount: Input should be a valid integer","errors":{"amount":"Input should be a valid integer"},"code":"GEN_002","request_id":"3f0e7c2a-9b4d-4e1a-8c6f-2d5b7a1e9c30"}}}}},"x-fastapi-operation-id":"mark_transactions_reviewed_by_filter_api_v1_transactions_batch_mark_reviewed_by_filter_post"}}},"components":{"schemas":{"SuccessEnvelope_TransactionReviewByFilterResponse_":{"properties":{"success":{"type":"boolean","title":"Success","default":true},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code"},"data":{"anyOf":[{"$ref":"#/components/schemas/TransactionReviewByFilterResponse"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"SuccessEnvelope[TransactionReviewByFilterResponse]"},"TransactionReviewByFilterRequest":{"properties":{"categorized_by":{"anyOf":[{"items":{"type":"string","enum":["rules","counterparty_default","merchant","historical","similarity","global_pattern","pfc","account_type","ai"]},"type":"array"},{"type":"null"}],"title":"Categorized By","description":"Who categorized the row (default: any machine layer). `rules` = a bank rule, `counterparty_default` = a counterparty rule, `merchant` = a known merchant pattern, the rest are learned or AI guesses."},"min_confidence":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Min Confidence","description":"Guesses (AI, history, similarity) need a stored confidence at or above this; bank rules, merchant patterns and counterparty defaults are exact matches and always pass."},"counterparties":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":200},{"type":"null"}],"title":"Counterparties","description":"Only these counterparties (case-insensitive exact names)."},"min_amount_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Min Amount Cents","description":"Only rows of at least this absolute amount."},"max_amount_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Max Amount Cents","description":"Only rows of at most this absolute amount."},"date_from":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date From","description":"Earliest transaction date."},"date_to":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date To","description":"Latest transaction date."},"limit":{"type":"integer","maximum":500.0,"minimum":1.0,"title":"Limit","description":"Most transactions to mark in one call.","default":500},"dry_run":{"type":"boolean","title":"Dry Run","description":"Return the count, amount and a sample; change nothing.","default":false}},"type":"object","title":"TransactionReviewByFilterRequest","description":"Mark every unreviewed, machine-categorized transaction that matches a filter.\n\nGive at least one filter. A row a person categorized, a transfer, an\nuncategorized or deleted row and an already-reviewed row are never selected."},"TransactionReviewByFilterResponse":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run"},"count":{"type":"integer","minimum":0.0,"title":"Count","description":"Transactions matching the filter."},"marked":{"type":"integer","minimum":0.0,"title":"Marked","description":"Transactions marked reviewed now."},"would_mark":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Would Mark","description":"On a dry run: how many this call would mark (<= limit)."},"remaining":{"type":"integer","minimum":0.0,"title":"Remaining","description":"Matches beyond limit; call again to take them.","default":0},"amount_total_cents":{"type":"integer","title":"Amount Total Cents","description":"Summed absolute amount of the matching transactions.","default":0},"sample":{"items":{"$ref":"#/components/schemas/TransactionReviewSampleRow"},"type":"array","title":"Sample"},"ids":{"items":{"type":"string"},"type":"array","title":"Ids","description":"Transaction ids this call selected."}},"type":"object","required":["dry_run","count","marked"],"title":"TransactionReviewByFilterResponse","description":"What a filter-based review matched and marked."},"TransactionReviewSampleRow":{"properties":{"transaction_id":{"type":"string","title":"Transaction Id"},"date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"counterparty":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Counterparty"},"amount_cents":{"type":"integer","title":"Amount Cents"},"categorized_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Categorized By"}},"type":"object","required":["transaction_id","amount_cents"],"title":"TransactionReviewSampleRow"},"ErrorResponse":{"title":"ErrorResponse","type":"object","description":"Envelope returned by every non-2xx response. Branch on `code` (stable) rather than `message` (human-readable, may change).","required":["error","message","code"],"properties":{"error":{"type":"string","description":"Error category: `validation_error`, `unauthorized`, `forbidden`, `not_found`, `conflict`, `rate_limited`, `server_error`, or `service_unavailable`."},"message":{"type":"string","description":"Human-readable explanation, safe to show to end users."},"code":{"type":"string","description":"Stable machine-readable code in `CATEGORY_NNN` form (e.g. `NOT_FOUND_006`, `AUTH_010`, `GEN_002`)."},"request_id":{"type":"string","description":"Correlation id for support requests. Echoes the `x-request-id` request header when one was supplied."},"errors":{"type":"object","additionalProperties":{"type":"string"},"description":"Field-level validation messages keyed by field name. Present on 400/422 validation failures only."}}}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Token","description":"API token authentication. Format: `Bearer dz_...`"}}},"security":[{"BearerAuth":[]}]}