{"openapi":"3.1.0","info":{"title":"PATCH /api/v1/reports/{report_id}","version":"1.0.0","description":"Update report sharing"},"servers":[{"url":"https://api.ondayzero.com","description":"Production"}],"paths":{"/api/v1/reports/{report_id}":{"patch":{"tags":["reports"],"summary":"Update report sharing","description":"Share a generated report to the client portal or take it back. Firm staff and business admins only.","operationId":"update_report","parameters":[{"name":"report_id","in":"path","required":true,"schema":{"type":"string","title":"Report Id"}},{"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/ReportUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope_ReportResponse_"}}}},"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"}}}},"404":{"description":"Not Found - Resource does not exist","content":{"application/json":{"example":{"error":"not_found","message":"Resource not found","code":"NOT_FOUND_001","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":"update_report_api_v1_reports__report_id__patch"}}},"components":{"schemas":{"ReportResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Unique identifier for this generated report. Use this ID to retrieve the report details or delete it. Example: '019ab37c-9071-7000-8000-000000000001'."},"business_id":{"type":"string","title":"Business Id","description":"UUID of the business this report belongs to. Reports are scoped to a single business and cannot be accessed by other businesses."},"report_name":{"type":"string","title":"Report Name","description":"The report type that was generated. Matches the report_name from the original request. Example: 'profit_and_loss', 'master_transactions', 'ar_report'."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"Timestamp when the report was generated (ISO 8601 format). Example: '2026-01-15T14:00:00Z'."},"downloaded_at":{"type":"string","format":"date-time","title":"Downloaded At","description":"Timestamp of the most recent download of this report. Updated each time the report is accessed. Useful for tracking report usage."},"s3_bucket":{"type":"string","title":"S3 Bucket","description":"Name of the S3 bucket where the report file is stored. Format: 'dayzero-{environment}-reports'. Example: 'dayzero-prod-reports'."},"s3_key":{"type":"string","title":"S3 Key","description":"S3 object key (path) for the report file within the bucket. Format: 'reports/{business_id}/{report_type}_{dates}.xlsx'. Example: 'reports/019ab37c-bus1/master_transactions_2026-01-01_2026-12-31.xlsx'."},"generation_params":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Generation Params","description":"Dictionary of all parameters used to generate this report. Includes resolved dates (even when using tax_year/tax_quarter), filters, and any additional parameters. Useful for understanding report scope and audit purposes. Example: {'start_date': '2026-01-01', 'end_date': '2026-12-31', 'ledger_id': null}."},"download_url":{"type":"string","title":"Download Url","description":"Same-origin proxy URL for downloading the report file. Streams through the backend to avoid CORS and presigned-URL expiration issues. Requires Authorization and x-business-id headers."},"generated_by_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Generated By Name","description":"Display name of the user who generated this report, e.g. 'Sarah Chen'. Extracted from generation_params."},"visible_to_client":{"type":"boolean","title":"Visible To Client","description":"Whether the report is shared to the client portal. Client users only ever see reports where this is true."},"filename":{"type":"string","title":"Filename","description":"Human download filename: business, report title and period, e.g. 'Acme Co - Quality of Earnings Workbook - 2024-01-01 to 2026-09-30.xlsx'."}},"type":"object","required":["id","business_id","report_name","created_at","downloaded_at","s3_bucket","s3_key","download_url","visible_to_client","filename"],"title":"ReportResponse","description":"Response schema for a generated report.\n\nContains the report metadata and a pre-signed URL to download the Excel file.\nReports are stored in S3 and the signed URL provides temporary access (24 hours).\n\nThe generation_params field stores all the parameters used to create this report,\nwhich is useful for understanding the report's scope and for regenerating it.","example":{"business_id":"019ab37c-b051-7000-8000-000000000001","created_at":"2024-01-15T14:00:00Z","download_url":"/api/v1/reports/download?s3_key=reports/019ab37c-bus1/profit_and_loss_2024-01.xlsx&filename=profit_and_loss_2024-01.xlsx","downloaded_at":"2024-01-15T14:00:00Z","filename":"Acme Co - Profit & Loss - 2024-01-01 to 2024-01-31.xlsx","generation_params":{"end_date":"2024-01-31","start_date":"2024-01-01"},"id":"019ab37c-9071-7000-8000-000000000001","report_name":"profit_and_loss","s3_bucket":"dayzero-reports","s3_key":"reports/019ab37c-bus1/profit_and_loss_2024-01.pdf","visible_to_client":true},"examples":[{"business_id":"019ab37c-b051-7000-8000-000000000001","created_at":"2024-01-15T14:00:00Z","download_url":"/api/v1/reports/download?s3_key=reports/019ab37c-bus1/profit_and_loss_2024-01.xlsx&filename=profit_and_loss_2024-01.xlsx","downloaded_at":"2024-01-15T14:00:00Z","filename":"Acme Co - Profit & Loss - 2024-01-01 to 2024-01-31.xlsx","generation_params":{"end_date":"2024-01-31","start_date":"2024-01-01"},"id":"019ab37c-9071-7000-8000-000000000001","report_name":"profit_and_loss","s3_bucket":"dayzero-reports","s3_key":"reports/019ab37c-bus1/profit_and_loss_2024-01.pdf","visible_to_client":true}]},"ReportUpdateRequest":{"properties":{"visible_to_client":{"type":"boolean","title":"Visible To Client","description":"True shares the report to the client portal; false keeps it internal to the firm."}},"type":"object","required":["visible_to_client"],"title":"ReportUpdateRequest","description":"Change how a generated report is shared."},"SuccessEnvelope_ReportResponse_":{"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/ReportResponse"},{"type":"null"}]}},"additionalProperties":true,"type":"object","title":"SuccessEnvelope[ReportResponse]"},"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":[]}]}