{"openapi":"3.1.0","paths":{"/auth/login":{"post":{"operationId":"login","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Authenticate with email + password. May require an MFA or tenant-selection step.","tags":["auth"]}},"/auth/select-tenant":{"post":{"operationId":"selectTenant","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectTenantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Exchange a selection token for tokens scoped to the chosen tenant.","tags":["auth"]}},"/auth/select-staff-portal":{"post":{"operationId":"selectStaffPortal","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectStaffPortalDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Exchange a selection token for a CaseWizard staff-management session.","tags":["auth"]}},"/auth/device/start":{"post":{"operationId":"startDeviceSignIn","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceStartDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceStartResponseDto"}}}}},"summary":"Start a device-code sign-in (RFC 8628) for an app that cannot run passkeys itself.","tags":["auth"]}},"/auth/device/lookup":{"get":{"operationId":"lookupDeviceSignIn","parameters":[{"name":"userCode","required":true,"in":"query","description":"The code shown in the requesting app.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceLookupResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Show who is asking to sign in with a device code, before the user approves it.","tags":["auth"]}},"/auth/device/approve":{"post":{"operationId":"approveDeviceSignIn","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceApproveDto"}}}},"responses":{"204":{"description":"Decision recorded."}},"security":[{"bearer":[]}],"summary":"Approve or deny a device-code sign-in for the current session's workspace.","tags":["auth"]}},"/auth/device/token":{"post":{"operationId":"exchangeDeviceCode","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceTokenDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"summary":"Poll for the session of an approved device code. Errors: authorization_pending, slow_down, access_denied, expired_token.","tags":["auth"]}},"/auth/tenants":{"get":{"operationId":"listMyTenants","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyTenantsResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List workspaces the signed-in identity may switch into.","tags":["auth"]}},"/auth/switch-tenant":{"post":{"operationId":"switchTenant","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchTenantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"security":[{"bearer":[]}],"summary":"Switch the current session to another tenant membership.","tags":["auth"]}},"/auth/switch-staff-portal":{"post":{"operationId":"switchStaffPortal","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionTransitionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"security":[{"bearer":[]}],"summary":"Switch the current session to CaseWizard Staff Management.","tags":["auth"]}},"/auth/exit-impersonation":{"post":{"operationId":"exitImpersonation","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionTransitionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"security":[{"bearer":[]}],"summary":"End impersonation (host staff or tenant Login-as) and restore the original session.","tags":["auth"]}},"/auth/mfa/verify":{"post":{"operationId":"verifyMfa","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaVerifyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Complete the MFA step of login with a code.","tags":["auth"]}},"/auth/mfa/enroll":{"post":{"operationId":"enrollMfa","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaEnrollDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaEnrollmentDto"}}}}},"security":[{"bearer":[]}],"summary":"Begin TOTP MFA enrollment (returns a QR/secret). Requires currentCode (step-up) if MFA is already enabled.","tags":["auth"]}},"/auth/mfa/activate":{"post":{"operationId":"activateMfa","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaActivateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaBackupCodesDto"}}}}},"security":[{"bearer":[]}],"summary":"Activate MFA by verifying a first code; returns backup codes.","tags":["auth"]}},"/auth/mfa/disable":{"post":{"operationId":"disableMfa","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MfaCodeDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Disable MFA for the current account. Requires a current TOTP or backup code (step-up).","tags":["auth"]}},"/auth/magic-link/request":{"post":{"operationId":"requestMagicLink","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MagicLinkRequestDto"}}}},"responses":{"204":{"description":""}},"summary":"Email a passwordless sign-in link (always 204; no user enumeration).","tags":["auth"]}},"/auth/magic-link/consume":{"post":{"operationId":"consumeMagicLink","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MagicLinkConsumeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Exchange a sign-in link token for tokens.","tags":["auth"]}},"/auth/passkey/register/options":{"post":{"operationId":"passkeyRegisterOptions","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}},"security":[{"bearer":[]}],"summary":"Get WebAuthn registration options for the current account.","tags":["auth"]}},"/auth/passkey/register/verify":{"post":{"operationId":"passkeyRegisterVerify","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyRegistrationVerifyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"verified":{"type":"boolean"}}}}}}},"security":[{"bearer":[]}],"summary":"Verify and store a new passkey for the current account.","tags":["auth"]}},"/auth/passkey/login/options":{"post":{"operationId":"passkeyLoginOptions","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyLoginOptionsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}},"summary":"Get WebAuthn assertion options for a sign-in attempt.","tags":["auth"]}},"/auth/passkey/login/verify":{"post":{"operationId":"passkeyLoginVerify","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyLoginVerifyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Verify a passkey assertion and establish a session.","tags":["auth"]}},"/auth/passkey/login/discover/options":{"post":{"operationId":"passkeyDiscoverLoginOptions","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}}},"summary":"Get WebAuthn assertion options for discoverable passkey sign-in (no email).","tags":["auth"]}},"/auth/passkey/login/discover/verify":{"post":{"operationId":"passkeyDiscoverLoginVerify","parameters":[{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyDiscoverVerifyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Verify a discoverable passkey assertion and establish a session.","tags":["auth"]}},"/auth/passkeys":{"get":{"operationId":"listPasskeys","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List passkeys registered on the current account.","tags":["auth"]}},"/auth/passkeys/{id}/revoke":{"post":{"operationId":"revokePasskey","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasskeyRevokeDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Remove a registered passkey. Requires a verification code when MFA is enabled.","tags":["auth"]}},"/auth/register":{"post":{"operationId":"register","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"summary":"Self-register into a tenant and receive tokens.","tags":["auth"]}},"/auth/signup":{"post":{"operationId":"signup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponseDto"}}}}},"summary":"Self-service signup: create a new firm, admin user, and receive login tokens.","tags":["auth"]}},"/auth/forgot-password":{"post":{"operationId":"forgotPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"}}}},"responses":{"204":{"description":""}},"summary":"Request a password reset (always 204; no user enumeration).","tags":["auth"]}},"/auth/confirm-email":{"post":{"operationId":"confirmEmail","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmEmailDto"}}}},"responses":{"204":{"description":""}},"summary":"Confirm an email address with a single-use token.","tags":["auth"]}},"/auth/activate":{"post":{"operationId":"activateAccount","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateAccountDto"}}}},"responses":{"204":{"description":""}},"summary":"Complete an activation email link: confirm the email address and, when the link allows it, set the password.","tags":["auth"]}},"/auth/reset-password":{"post":{"operationId":"resetPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"}}}},"responses":{"204":{"description":""}},"summary":"Set a new password using a reset token.","tags":["auth"]}},"/auth/change-password":{"post":{"operationId":"changePassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Change the signed-in user's password (re-authenticates with the current password).","tags":["auth"]}},"/auth/refresh":{"post":{"operationId":"refresh","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"summary":"Rotate the refresh token, mint a new access token.","tags":["auth"]}},"/auth/logout":{"post":{"operationId":"logout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogoutDto"}}}},"responses":{"204":{"description":""}},"summary":"Revoke a refresh token.","tags":["auth"]}},"/auth/token":{"post":{"operationId":"oauthToken","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthTokenResponseDto"}}}}},"summary":"OAuth2 client-credentials grant: exchange client id/secret for an access token.","tags":["auth"]}},"/auth/me":{"get":{"operationId":"getCurrentUser","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUserDto"}}}}},"security":[{"bearer":[]}],"summary":"Current authenticated user and permissions.","tags":["auth"]},"patch":{"operationId":"updateCurrentUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCurrentUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUserDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the signed-in user's own profile (name, phone, username).","tags":["auth"]}},"/auth/me/ui-preference":{"patch":{"operationId":"updateUiPreference","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUiPreferenceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUserDto"}}}}},"security":[{"bearer":[]}],"summary":"Choose the classic or new web UI (new requires early access for the tenant).","tags":["auth"]}},"/auth/login-attempts":{"get":{"operationId":"listLoginAttempts","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginAttemptListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Recent login attempts (success and failure) for the current account.","tags":["auth"]}},"/auth/me/avatar":{"get":{"operationId":"getAvatar","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarDto"}}}}},"security":[{"bearer":[]}],"summary":"The signed-in user's profile picture (stored in object storage; returned as a data URL).","tags":["auth"]},"post":{"operationId":"uploadAvatar","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarDto"}}}}},"security":[{"bearer":[]}],"summary":"Upload/replace the signed-in user's profile picture to object storage (JPEG or PNG, <= 1 MB; returned as a data URL).","tags":["auth"]},"delete":{"operationId":"deleteAvatar","parameters":[],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Remove the signed-in user's profile picture from object storage.","tags":["auth"]}},"/invoices/{id}/email":{"post":{"operationId":"emailInvoice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDocumentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Email an invoice PDF to a recipient.","tags":["billing-mail"]}},"/invoices/email-batch":{"post":{"operationId":"emailInvoiceBatch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailInvoiceBatchDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailInvoiceBatchResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Email each invoice to its billing-entity contact email.","tags":["billing-mail"]}},"/cases/{caseId}/statement/email":{"post":{"operationId":"emailCaseStatement","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailCaseStatementDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Email the case's live statement PDF (the same PDF as POST /cases/{caseId}/statement/pdf). The recipient defaults to the billing-entity contact email.","tags":["billing-mail"]}},"/statements/{id}/email":{"post":{"operationId":"emailStatement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailDocumentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Email a statement PDF to a recipient.","tags":["billing-mail"]}},"/reports/{reportKey}":{"post":{"operationId":"createReport","parameters":[{"name":"reportKey","required":true,"in":"path","description":"case-event | case-events | case-notes | case-detail-input | case-detail | plaintiff-detail | time-entry | pre-bill-worksheet","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportParamsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Render a case report to PDF (enqueues a job; poll for the file).","tags":["reports"]}},"/reports/jobs/{jobId}":{"get":{"operationId":"getOutputJob","parameters":[{"name":"jobId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobStatusDto"}}}}},"security":[{"bearer":[]}],"summary":"Status (and result reference) of a report/export/PDF job.","tags":["jobs"]}},"/invoices":{"get":{"operationId":"listInvoices","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Matches the case style or number, the billing entity name, or the invoice number (a prefixed number such as \"INV-10001\" also matches).","schema":{"type":"string"}},{"name":"caseId","required":false,"in":"query","schema":{"type":"number"}},{"name":"invoiceStageId","required":false,"in":"query","description":"Filter by stage id.","schema":{"type":"number"}},{"name":"noPayments","required":false,"in":"query","description":"Only invoices with no payments yet: stage Open, Printed or Emailed (stage below Paid; Paid and Partial Payment are excluded). Legacy \"All No Payments\".","schema":{"type":"boolean"}},{"name":"from","required":false,"in":"query","description":"ISO date lower bound on invoice date.","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO date upper bound on invoice date; a date (yyyy-mm-dd) includes its whole UTC day.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List invoices (paginated).","tags":["invoices"]},"post":{"operationId":"createManualInvoice","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateManualInvoiceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDetailDto"}}}},"400":{"description":"Case is missing a billing entity."},"409":{"description":"Invoice number already exists."}},"security":[{"bearer":[]}],"summary":"Create a manual invoice. Attaches all of the case's un-invoiced expenses and copies isFinal to the case.","tags":["invoices"]}},"/invoices/new":{"get":{"operationId":"getNewInvoiceDefaults","parameters":[{"name":"caseId","required":false,"in":"query","description":"Case the new invoice is for (echoed back).","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewInvoiceDefaultsDto"}}}}},"security":[{"bearer":[]}],"summary":"Defaults for a new manual invoice: next number, today, Open stage, terms and stages.","tags":["invoices"]}},"/invoices/fixed-fee":{"get":{"operationId":"getCaseFixedFee","parameters":[{"name":"caseId","required":true,"in":"query","description":"Case whose fixed fee position to read.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FixedFeePositionDto"}}}},"404":{"description":"Case not found, or its billing entity is not Fixed Fee."}},"security":[{"bearer":[]}],"summary":"A case's fixed fee: the fee, what is already billed and what is left to bill.","tags":["invoices"]},"post":{"operationId":"createFixedFeeInvoice","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFixedFeeInvoiceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDetailDto"}}}},"400":{"description":"Case has no Fixed Fee billing entity, or the amount is more than is left to bill."}},"security":[{"bearer":[]}],"summary":"Bill a case's fixed fee, whole or in part, on its own invoice with just the fee line, on the given date.","tags":["invoices"]}},"/invoices/batch":{"post":{"operationId":"generateInvoicesBatch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchInvoiceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchInvoiceResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Generate a pre-bill and invoice for each listed case over one period.","tags":["invoices"]}},"/invoices/from-pre-bill/{preBillId}":{"post":{"operationId":"generateInvoiceFromPreBill","parameters":[{"name":"preBillId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Generate an invoice from a pre-bill.","tags":["invoices"]}},"/invoices/{id}":{"get":{"operationId":"getInvoice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an invoice (with totals) by id.","tags":["invoices"]},"patch":{"operationId":"updateInvoice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvoiceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an invoice (dates, terms, stage, fixed fee, final, case).","tags":["invoices"]},"delete":{"operationId":"deleteInvoice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an invoice and release its time and expenses. Refused (400) while payments are recorded on it.","tags":["invoices"]}},"/webhooks":{"get":{"operationId":"listWebhooks","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDto"}}}}}},"security":[{"bearer":[]}],"summary":"List webhook subscriptions.","tags":["webhooks"]},"post":{"operationId":"createWebhook","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedWebhookDto"}}}}},"security":[{"bearer":[]}],"summary":"Subscribe to events (secret shown once).","tags":["webhooks"]}},"/webhooks/{id}":{"patch":{"operationId":"updateWebhook","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWebhookDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a webhook subscription.","tags":["webhooks"]},"delete":{"operationId":"deleteWebhook","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a webhook subscription.","tags":["webhooks"]}},"/pre-bills":{"get":{"operationId":"listPreBills","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"caseId","required":false,"in":"query","schema":{"type":"number"}},{"name":"invoiced","required":false,"in":"query","description":"true = only pre-bills already turned into an invoice.","schema":{"type":"boolean"}},{"name":"search","required":false,"in":"query","description":"Match case style, billing entity name, or numeric id.","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","schema":{"example":"2026-05-01","type":"string"}},{"name":"endDate","required":false,"in":"query","schema":{"example":"2026-05-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreBillListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List pre-bills (paginated).","tags":["pre-bills"]}},"/pre-bills/generate":{"post":{"operationId":"generatePreBill","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GeneratePreBillDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreBillDto"}}}}},"security":[{"bearer":[]}],"summary":"Generate a pre-bill from approved, unbilled time on a case.","tags":["pre-bills"]}},"/pre-bills/batch":{"post":{"operationId":"batchPreBills","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchPreBillDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchPreBillResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Batch-generate pre-bills for all cases with a billing entity and eligible time (legacy BatchPreBill).","tags":["pre-bills"]}},"/pre-bills/{id}":{"get":{"operationId":"getPreBill","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreBillDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a pre-bill by id (worksheet detail).","tags":["pre-bills"]},"patch":{"operationId":"updatePreBill","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePreBillDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreBillDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Edit pre-bill notes.","tags":["pre-bills"]},"delete":{"operationId":"deletePreBill","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete an un-invoiced pre-bill, releasing its time back to Approved (same semantics as reject).","tags":["pre-bills"]}},"/pre-bills/delete":{"post":{"operationId":"deletePreBills","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePreBillsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletePreBillsResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Delete many un-invoiced pre-bills in one call, releasing their time back to Approved. Invoiced or missing ids are reported in `failed`.","tags":["pre-bills"]}},"/pre-bills/{id}/update-rates":{"post":{"operationId":"updatePreBillRates","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreBillDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Recalculate rate and amount for uninvoiced timers on this pre-bill (legacy UpdatePreBillTimerRates).","tags":["pre-bills"]}},"/pre-bills/{id}/reject":{"post":{"operationId":"rejectPreBill","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Reject a pre-bill: release its time back to Approved and remove it.","tags":["pre-bills"]}},"/billing-settings":{"get":{"operationId":"getBillingSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the tenant's billing settings.","tags":["billing-settings"]},"patch":{"operationId":"updateBillingSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillingSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the tenant's billing settings.","tags":["billing-settings"]}},"/statements":{"get":{"operationId":"listStatements","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"billingEntityId","required":false,"in":"query","description":"Filter by billing entity.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List statements (paginated).","tags":["statements"]}},"/statements/generate":{"post":{"operationId":"generateStatement","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateStatementDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementDto"}}}}},"security":[{"bearer":[]}],"summary":"Generate a statement for a billing entity.","tags":["statements"]}},"/statements/by-case":{"get":{"operationId":"listStatementsByCase","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"balanceDue","required":false,"in":"query","description":"Only invoices with a balance above zero (legacy default). Applied per invoice before grouping, so a case appears when it has at least one open invoice. false lists every invoiced case, including settled ones.","schema":{"default":true,"type":"boolean"}},{"name":"billingEntityId","required":false,"in":"query","description":"Only cases billed to this billing entity.","schema":{"type":"number"}},{"name":"filter","required":false,"in":"query","description":"Case-insensitive substring match on case number, case style or billing entity name.","schema":{"type":"string"}},{"name":"asOf","required":false,"in":"query","description":"As-of date for the aging (defaults to now), same rule as GET /cases/{id}/statement.","schema":{"example":"2026-06-30","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementsByCaseResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Live statements by case (legacy statements list): per-case billed, paid, write-off, balance and aging (Current, 31-60, 61-90, 91+ days past due).","tags":["statements"]}},"/statements/{id}":{"get":{"operationId":"getStatement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatementDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a statement by id.","tags":["statements"]},"delete":{"operationId":"deleteStatement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a statement.","tags":["statements"]}},"/cases/{id}/statement":{"get":{"operationId":"getCaseStatement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"asOf","required":false,"in":"query","description":"As-of date for the statement and its aging (defaults to now). Aging is measured in whole days past each invoice due date (the invoice date when there is no due date).","schema":{"example":"2026-06-30","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseStatementDto"}}}}},"security":[{"bearer":[]}],"summary":"The case's live statement: invoices with a balance above zero, payments, write-offs and aging (Current, 31-60, 61-90, 91+ days past due).","tags":["statements"]}},"/billing/reports/billed-collected":{"get":{"operationId":"getBilledCollectedReport","parameters":[{"name":"basis","required":false,"in":"query","description":"Date basis. invoiceDate (default) filters by invoice date (startDate/endDate). paymentDate filters by payment date (paymentsStartDate/paymentsEndDate) and ignores the invoice-date range. All ranges are inclusive whole UTC days. With paymentDate, only invoices with at least one payment in the window are listed, the collected and write-off columns count in-window payments only, and balance is total billed minus those in-window payments and write-offs (legacy semantics; not the true outstanding balance).","schema":{"default":"invoiceDate","type":"string","enum":["invoiceDate","paymentDate"]}},{"name":"filter","required":false,"in":"query","description":"Case-insensitive match on billing entity name.","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"invoiceDate basis: only invoices dated on/after this UTC day.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"invoiceDate basis: only invoices dated on/before this UTC day (inclusive).","schema":{"type":"string"}},{"name":"paymentsStartDate","required":false,"in":"query","description":"paymentDate basis: first UTC day of the payments window. With the invoiceDate basis it only narrows the collected columns; that combined use is deprecated, use basis=paymentDate.","schema":{"type":"string"}},{"name":"paymentsEndDate","required":false,"in":"query","description":"paymentDate basis: last UTC day (inclusive) of the payments window. With the invoiceDate basis it only narrows the collected columns; that combined use is deprecated.","schema":{"type":"string"}},{"name":"billingEntityId","required":false,"in":"query","description":"Restrict to a single billing entity.","schema":{"type":"number"}},{"name":"attorneyId","required":false,"in":"query","description":"Restrict to cases whose attorney of record is this user (legacy only used the attorney as the report header label); attorneyName carries the label.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BilledCollectedReportDto"}}}}},"security":[{"bearer":[]}],"summary":"Billed-vs-collected totals grouped by client, by invoice date or payment date.","tags":["billing-reports"]}},"/billing/reports/billed-collected/detail":{"get":{"operationId":"getBilledCollectedDetail","parameters":[{"name":"basis","required":false,"in":"query","description":"Date basis. invoiceDate (default) filters by invoice date (startDate/endDate). paymentDate filters by payment date (paymentsStartDate/paymentsEndDate) and ignores the invoice-date range. All ranges are inclusive whole UTC days. With paymentDate, only invoices with at least one payment in the window are listed, the collected and write-off columns count in-window payments only, and balance is total billed minus those in-window payments and write-offs (legacy semantics; not the true outstanding balance).","schema":{"default":"invoiceDate","type":"string","enum":["invoiceDate","paymentDate"]}},{"name":"filter","required":false,"in":"query","description":"Case-insensitive match on billing entity name.","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"invoiceDate basis: only invoices dated on/after this UTC day.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"invoiceDate basis: only invoices dated on/before this UTC day (inclusive).","schema":{"type":"string"}},{"name":"paymentsStartDate","required":false,"in":"query","description":"paymentDate basis: first UTC day of the payments window. With the invoiceDate basis it only narrows the collected columns; that combined use is deprecated, use basis=paymentDate.","schema":{"type":"string"}},{"name":"paymentsEndDate","required":false,"in":"query","description":"paymentDate basis: last UTC day (inclusive) of the payments window. With the invoiceDate basis it only narrows the collected columns; that combined use is deprecated.","schema":{"type":"string"}},{"name":"billingEntityId","required":false,"in":"query","description":"Restrict to a single billing entity.","schema":{"type":"number"}},{"name":"attorneyId","required":false,"in":"query","description":"Restrict to cases whose attorney of record is this user (legacy only used the attorney as the report header label); attorneyName carries the label.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BilledCollectedRowDto"}}}}}},"security":[{"bearer":[]}],"summary":"Per-invoice billed-collected rows (deterministic rebuild of vBilledCollected).","tags":["billing-reports"]}},"/billing/reports/collections-by-attorney":{"get":{"operationId":"getCollectionsByAttorneyReport","parameters":[{"name":"basis","required":false,"in":"query","description":"Date basis. invoiceDate (default) filters by invoice date (startDate/endDate). paymentDate filters by payment date (paymentsStartDate/paymentsEndDate) and ignores the invoice-date range. All ranges are inclusive whole UTC days.","schema":{"default":"invoiceDate","type":"string","enum":["invoiceDate","paymentDate"]}},{"name":"startDate","required":false,"in":"query","description":"invoiceDate basis: first invoice UTC day.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"invoiceDate basis: last invoice UTC day (inclusive).","schema":{"type":"string"}},{"name":"paymentsStartDate","required":false,"in":"query","description":"paymentDate basis: first payment UTC day.","schema":{"type":"string"}},{"name":"paymentsEndDate","required":false,"in":"query","description":"paymentDate basis: last payment UTC day (inclusive).","schema":{"type":"string"}},{"name":"attorneyId","required":false,"in":"query","description":"Restrict to one timekeeper (user id).","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectionsByAttorneyReportDto"}}}}},"security":[{"bearer":[]}],"summary":"Billed and collected per timekeeper by month, pro-rated by their share of invoice fees.","tags":["billing-reports"]}},"/billing/reports/payments":{"get":{"operationId":"getPaymentsReport","parameters":[{"name":"startDate","required":false,"in":"query","description":"First invoice UTC day. When an invoice-date bound is given, groups are invoice months.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"Last invoice UTC day (inclusive).","schema":{"type":"string"}},{"name":"paymentsStartDate","required":false,"in":"query","description":"First payment UTC day.","schema":{"type":"string"}},{"name":"paymentsEndDate","required":false,"in":"query","description":"Last payment UTC day (inclusive).","schema":{"type":"string"}},{"name":"filter","required":false,"in":"query","description":"Case-insensitive match on case style, client name, invoice number (with or without its prefix) or check number.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentsReportDto"}}}}},"security":[{"bearer":[]}],"summary":"Payments grouped by invoice month or payment month.","tags":["billing-reports"]}},"/billing/reports/ar-aging":{"get":{"operationId":"getArAgingReport","parameters":[{"name":"filter","required":false,"in":"query","description":"Case-insensitive match on billing entity name.","schema":{"type":"string"}},{"name":"asOf","required":false,"in":"query","description":"As-of date for aging (defaults to today). Buckets are measured from the due date.","schema":{"type":"string"}},{"name":"attorneyId","required":false,"in":"query","description":"Restrict to cases whose attorney of record is this user.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArAgingReportDto"}}}}},"security":[{"bearer":[]}],"summary":"Accounts-receivable aging grouped by client (0-30/31-60/61-90/91+).","tags":["billing-reports"]}},"/audit-logs":{"get":{"operationId":"listAuditLogs","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"resource","required":false,"in":"query","description":"Filter by resource tag (e.g. cases).","schema":{"type":"string"}},{"name":"actorUserId","required":false,"in":"query","description":"Filter by acting user id.","schema":{"type":"string"}},{"name":"action","required":false,"in":"query","description":"Filter by HTTP action (GET/POST/PUT/PATCH/DELETE) or LOGIN.","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"ISO date lower bound on creation time.","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO date upper bound on creation time.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List audit-trail entries (newest first).","tags":["audit-logs"]}},"/me/microsoft":{"get":{"operationId":"getMicrosoftConnection","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicrosoftConnectionDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the current user's Microsoft connection status.","tags":["microsoft"]},"delete":{"operationId":"disconnectMicrosoft","parameters":[],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Forget the current user's stored Microsoft credential.","tags":["microsoft"]}},"/me/microsoft/authorize-url":{"post":{"description":"Returns the authorize URL as JSON rather than redirecting, because the web app proxies API calls with redirect:\"manual\". Navigate with window.location.assign(authorizeUrl).","operationId":"createMicrosoftAuthorizeUrl","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeUrlRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthorizeUrlDto"}}}},"409":{"description":"SharePoint is not configured for this firm."}},"security":[{"bearer":[]}],"summary":"Start a Microsoft connect flow and return the URL to send the browser to.","tags":["microsoft"]}},"/me/microsoft/callback":{"post":{"operationId":"completeMicrosoftConnect","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicrosoftCallbackDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MicrosoftCallbackResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Complete the Microsoft connect flow with the code and state from the redirect.","tags":["microsoft"]}},"/me/egnyte":{"get":{"operationId":"getEgnyteConnection","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteConnectionDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the current user's Egnyte connection status.","tags":["egnyte"]},"delete":{"operationId":"disconnectEgnyte","parameters":[],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Disconnect the current user from Egnyte.","tags":["egnyte"]}},"/me/egnyte/authorize-url":{"post":{"operationId":"createEgnyteAuthorizeUrl","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteAuthorizeUrlRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteAuthorizeUrlDto"}}}}},"security":[{"bearer":[]}],"summary":"Start an Egnyte connect flow and return the URL to send the browser to.","tags":["egnyte"]}},"/me/egnyte/callback":{"post":{"operationId":"completeEgnyteConnect","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteCallbackDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteCallbackResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Complete an Egnyte connect flow with the authorization code.","tags":["egnyte"]}},"/tenant-settings/user-management":{"get":{"operationId":"getUserManagementSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserManagementSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the firm's user-management and login policy settings.","tags":["user-management-settings"]},"put":{"operationId":"updateUserManagementSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserManagementSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserManagementSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the firm's user-management and login policy settings.","tags":["user-management-settings"]}},"/health":{"get":{"operationId":"health","parameters":[],"responses":{"200":{"description":""}},"summary":"Liveness probe.","tags":["system"]}},"/ready":{"get":{"operationId":"ready","parameters":[],"responses":{"200":{"description":""}},"summary":"Readiness probe (Postgres + Redis).","tags":["system"]}},"/version":{"get":{"operationId":"version","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VersionDto"}}}}},"summary":"Build identity (ADR-0006).","tags":["system"]}},"/cases":{"get":{"operationId":"listCases","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Free-text search. Words are AND-ed; each word is matched case-insensitively against case number, case style, remarks, case type, the names of the plaintiff / defendant / insurer (person or organisation), and the assigned user, attorney of record and secondary user. A word of 4+ digits additionally matches an SSN fragment, gated on People.View (the same permission GET /people requires for SSN search) and never available to API clients. Every such search is rate-capped and audited (R6); when the cap is reached the SSN match is skipped and the remaining fields still return, rather than failing the request.","schema":{"maxLength":200,"type":"string"}},{"name":"status","required":false,"in":"query","description":"Lifecycle filter: open matches isActive=true, closed matches isActive=false.","schema":{"default":"all","type":"string","enum":["open","closed","all"]}},{"name":"caseTypeId","required":false,"in":"query","schema":{"type":"number"}},{"name":"mine","required":false,"in":"query","description":"Only cases the signed-in user is on: assigned user, attorney of record or secondary user (legacy \"My cases\"). Ignored for third-party principals, which have no user identity.","schema":{"type":"boolean"}},{"name":"sort","required":false,"in":"query","description":"Sort field. Default creationTime keeps existing list behavior. The display columns sort by what the list shows: caseStyle falls back to the case number, plaintiff and defendant are the first such party (a person by \"first last\", else an organization), insurer is the adjuster organization, and assignedToName is the assigned user's full name. Cases with no value for the column come last in either direction, ties break by id.","schema":{"default":"creationTime","type":"string","enum":["creationTime","lastModificationTime","caseStyle","caseKey","caseTypeName","plaintiff","defendant","insurer","isActive","assignedToName","statutoryDeadline"]}},{"name":"order","required":false,"in":"query","description":"Sort direction. Default desc pairs with creationTime for newest-first lists.","schema":{"default":"desc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List cases (paginated, filterable).","tags":["cases"]},"post":{"operationId":"createCase","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCaseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a case.","tags":["cases"]}},"/case-types":{"get":{"operationId":"listCaseTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseTypeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List case types for the tenant.","tags":["cases"]}},"/case-types/{id}/tabs":{"get":{"description":"Which optional case tabs (Liens, Injuries, Medical Expenses, Settlements, Criminal Charges, Victims, Arresting Officers) and plaintiff sections a case type shows, seeded from legacy CaseTabs and PlaintiffTabs. Read-only; also embedded as `tabs` on a case. Responds 404 when the case type does not exist or has no tab configuration.","operationId":"getCaseTypeTabs","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseTypeTabsDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the case-page tab configuration of a case type.","tags":["cases"]}},"/case-summary-classes":{"get":{"description":"The per-case-type Case Summary tile set (legacy CaseSummaryClass): name is the tile component key, label the caption, sortOrder the display order, personRoleId an optional person-role constraint. Returned flat and ordered; the synthetic Case tile is not included.","operationId":"listCaseSummaryClasses","parameters":[{"name":"caseTypeId","required":false,"in":"query","description":"Filter summary classes by case type.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseSummaryClassDto"}}}}}},"security":[{"bearer":[]}],"summary":"List Case Summary tile configuration.","tags":["cases"]}},"/cases/key/{key}":{"get":{"operationId":"getCaseByKey","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a case by its case key (the number shown in case URLs).","tags":["cases"]}},"/cases/{id}":{"get":{"operationId":"getCase","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a case by id.","tags":["cases"]},"patch":{"description":"Closed cases (isActive=false) are read-only and respond 409, except for a patch that sets isActive=true to reopen the case.","operationId":"updateCase","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a case.","tags":["cases"]},"delete":{"description":"Permanently removes the case from all API queries (soft delete, permission-gated by Cases.Delete), together with every record that only belongs to it: participants and their medical records, events and notes, documents, detail fields, history requests, liens, settlements, and criminal-case records. Audit logs and shared people/organizations are kept. A case with any time entries, expenses, pre-bills or invoices cannot be deleted (409 CASE_HAS_BILLING): close it with closeCase instead, which keeps it available for history, reporting, and billing.","operationId":"deleteCase","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":"Deleted."},"409":{"description":"The case has billing and must be closed instead (code CASE_HAS_BILLING)."}},"security":[{"bearer":[]}],"summary":"Delete a case (soft delete).","tags":["cases"]}},"/cases/{id}/close":{"post":{"description":"Marks the case closed (isActive=false, isFinal=true). The case and all related records are preserved and remain retrievable by id and listable with status=closed or status=all, but mutations of the case and its records (events, time entries, expenses, participants, documents, liens, settlements) are rejected with 409 while closed. Use reopenCase to restore it to open lists. Distinct from deleteCase, which removes the case from all queries.","operationId":"closeCase","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDto"}}}}},"security":[{"bearer":[]}],"summary":"Close a case (non-destructive).","tags":["cases"]}},"/cases/{id}/reopen":{"post":{"description":"Clears the closed flags (isActive=true, isFinal=false) so the case appears in open lists again.","operationId":"reopenCase","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDto"}}}}},"security":[{"bearer":[]}],"summary":"Reopen a closed case.","tags":["cases"]}},"/people":{"get":{"operationId":"listPeople","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on first/last name.","schema":{"type":"string"}},{"name":"ssn","required":false,"in":"query","description":"SSN substring (digits only). Minimum 4 digits (anti-enumeration, R6).","schema":{"type":"string"}},{"name":"personTypeId","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List people (name + SSN substring search).","tags":["people"]},"post":{"operationId":"createPerson","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePersonDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a person (with optional contact).","tags":["people"]}},"/people/{id}":{"get":{"operationId":"getPerson","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a person by id (SSN/DL masked).","tags":["people"]},"patch":{"operationId":"updatePerson","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePersonDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a person.","tags":["people"]},"delete":{"operationId":"deletePerson","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":"Deleted."},"409":{"description":"The person is still linked to cases or billing entities (code CONTACT_IN_USE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInUseErrorDto"}}}}},"security":[{"bearer":[]}],"summary":"Soft-delete a person. Refused with 409 CONTACT_IN_USE while still linked.","tags":["people"]}},"/people/{id}/pii":{"get":{"operationId":"revealPersonPii","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PersonPiiDto"}}}}},"security":[{"bearer":[]}],"summary":"Reveal a person unmasked SSN/DL. First-party users only; every reveal is audited (R6).","tags":["people"]}},"/people/{id}/usage":{"get":{"operationId":"getPersonUsage","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactUsageDto"}}}}},"security":[{"bearer":[]}],"summary":"Where this person is linked: live cases (with roles), billing entities and per-table counts.","tags":["people"]}},"/organizations":{"get":{"operationId":"listOrganizations","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on organization name.","schema":{"type":"string"}},{"name":"organizationTypeId","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List organizations.","tags":["organizations"]},"post":{"operationId":"createOrganization","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an organization.","tags":["organizations"]}},"/organizations/{id}":{"get":{"operationId":"getOrganization","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an organization by id.","tags":["organizations"]},"patch":{"operationId":"updateOrganization","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an organization.","tags":["organizations"]},"delete":{"operationId":"deleteOrganization","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":"Deleted."},"409":{"description":"The organization is still linked to cases or billing entities (code CONTACT_IN_USE).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInUseErrorDto"}}}}},"security":[{"bearer":[]}],"summary":"Soft-delete an organization. Refused with 409 CONTACT_IN_USE while still linked.","tags":["organizations"]}},"/organizations/{id}/usage":{"get":{"operationId":"getOrganizationUsage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactUsageDto"}}}}},"security":[{"bearer":[]}],"summary":"Where this organization is linked: live cases (with roles), billing entities and per-table counts.","tags":["organizations"]}},"/cases/{caseId}/participants":{"get":{"operationId":"listCaseParticipants","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"participantType","required":false,"in":"query","description":"Filter by participant type.","schema":{"type":"string","enum":["PLAINTIFF","DEFENDANT","ADJUSTER","OPPOSING_COUNSEL","CASE_MANAGER","JUDGE","PHYSICAL_THERAPIST","REHAB_COUNSELOR","WITNESS","RELATIVE"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List participants on a case.","tags":["participants"]},"post":{"operationId":"createCaseParticipant","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateParticipantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a participant to a case.","tags":["participants"]}},"/cases/{caseId}/plaintiffs":{"get":{"operationId":"listCasePlaintiffs","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"participantType","required":false,"in":"query","description":"Filter by participant type.","schema":{"type":"string","enum":["PLAINTIFF","DEFENDANT","ADJUSTER","OPPOSING_COUNSEL","CASE_MANAGER","JUDGE","PHYSICAL_THERAPIST","REHAB_COUNSELOR","WITNESS","RELATIVE"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List plaintiffs on a case.","tags":["participants"]},"post":{"operationId":"createCasePlaintiff","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlaintiffDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a plaintiff to a case.","tags":["participants"]}},"/plaintiffs/{id}":{"get":{"operationId":"getPlaintiff","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a plaintiff by participant id.","tags":["participants"]}},"/participants/{id}":{"get":{"operationId":"getParticipant","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a participant by id.","tags":["participants"]},"patch":{"operationId":"updateParticipant","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateParticipantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParticipantDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a participant.","tags":["participants"]},"delete":{"operationId":"deleteParticipant","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a participant.","tags":["participants"]}},"/case-detail-field-types":{"get":{"operationId":"listCaseDetailFieldTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseDetailFieldTypeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List EAV field-type catalog.","tags":["case-detail-fields"]}},"/case-detail-fields":{"get":{"operationId":"listCaseDetailDefinitions","parameters":[{"name":"caseTypeId","required":false,"in":"query","description":"Filter definitions by case type.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseDetailClassDto"}}}}}},"security":[{"bearer":[]}],"summary":"List detail classes and their fields.","tags":["case-detail-fields"]},"post":{"operationId":"createCaseDetailField","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCaseDetailFieldDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDetailFieldDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a detail field.","tags":["case-detail-fields"]}},"/case-detail-classes":{"post":{"operationId":"createCaseDetailClass","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCaseDetailClassDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDetailClassDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a detail class.","tags":["case-detail-fields"]}},"/case-detail-classes/{id}":{"patch":{"operationId":"updateCaseDetailClass","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseDetailClassDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDetailClassDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a detail class.","tags":["case-detail-fields"]},"delete":{"operationId":"deleteCaseDetailClass","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a detail class.","tags":["case-detail-fields"]}},"/case-detail-fields/{id}":{"patch":{"operationId":"updateCaseDetailField","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseDetailFieldDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseDetailFieldDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a detail field.","tags":["case-detail-fields"]},"delete":{"operationId":"deleteCaseDetailField","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a detail field.","tags":["case-detail-fields"]}},"/cases/{caseId}/detail-fields":{"get":{"operationId":"getCaseDetailValues","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseDetailValueDto"}}}}}},"security":[{"bearer":[]}],"summary":"Get EAV values for a case.","tags":["case-detail-fields"]},"put":{"operationId":"setCaseDetailValues","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetCaseDetailValuesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CaseDetailValueDto"}}}}}},"security":[{"bearer":[]}],"summary":"Upsert EAV values for a case.","tags":["case-detail-fields"]}},"/document-categories":{"get":{"operationId":"listDocumentCategories","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentCategoryDto"}}}}}},"security":[{"bearer":[]}],"summary":"List document categories.","tags":["documents"]},"post":{"operationId":"createDocumentCategory","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDocumentCategoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentCategoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a document category.","tags":["documents"]}},"/cases/{caseId}/documents":{"get":{"operationId":"listCaseDocuments","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on file name.","schema":{"type":"string"}},{"name":"documentCategoryId","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List documents on a case.","tags":["documents"]},"post":{"operationId":"registerCaseDocument","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDocumentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDto"}}}}},"security":[{"bearer":[]}],"summary":"Register a SharePoint document against a case (metadata only).","tags":["documents"]}},"/cases/{caseId}/documents/browse":{"get":{"description":"Reads SharePoint directly rather than returning registered rows, so files added straight in SharePoint appear with no sync step. Creates the case folder on first view. Requires a connected Microsoft account: responds 409 MICROSOFT_NOT_CONNECTED when there is none, and 403 SHAREPOINT_ACCESS_DENIED when the user has no access to the site.","operationId":"browseCaseDocuments","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"path","required":false,"in":"query","description":"Folder to list, relative to the listing root. Omit for the root itself.","schema":{"example":"Medical","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveListingDto"}}}},"409":{"description":"Microsoft not connected, or SharePoint not configured."}},"security":[{"bearer":[]}],"summary":"Live listing of a case's SharePoint folder, read as the signed-in user.","tags":["documents"]}},"/documents/templates/browse":{"get":{"operationId":"browseDocumentTemplates","parameters":[{"name":"path","required":false,"in":"query","description":"Folder to list, relative to the listing root. Omit for the root itself.","schema":{"example":"Medical","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DriveListingDto"}}}},"409":{"description":"Microsoft not connected, or no template folder configured."}},"security":[{"bearer":[]}],"summary":"Live listing of the firm's SharePoint template folder.","tags":["documents"]}},"/documents/{id}":{"get":{"operationId":"getDocument","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDto"}}}}},"security":[{"bearer":[]}],"summary":"Get document metadata by id.","tags":["documents"]},"patch":{"operationId":"updateDocument","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDocumentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDto"}}}}},"security":[{"bearer":[]}],"summary":"Update document metadata.","tags":["documents"]},"delete":{"operationId":"deleteDocument","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a document (metadata).","tags":["documents"]}},"/documents/{id}/download":{"get":{"operationId":"getDocumentDownload","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentDownloadDto"}}}}},"security":[{"bearer":[]}],"summary":"Resolve a SharePoint view/download URL.","tags":["documents"]}},"/tenant-settings/document-storage":{"get":{"operationId":"getDocumentStorageSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentStorageSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the firm's active document storage provider.","tags":["document-storage-settings"]},"put":{"operationId":"updateDocumentStorageSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDocumentStorageSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentStorageSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Switch the firm's document storage provider (exclusive XOR).","tags":["document-storage-settings"]}},"/tenant-settings/sharepoint":{"get":{"operationId":"getSharepointSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharepointSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the firm's SharePoint configuration.","tags":["sharepoint-settings"]},"put":{"description":"Saving a site URL resolves it to stable Graph ids using the caller's own Microsoft account, so an unreachable site is rejected here rather than breaking documents later.","operationId":"updateSharepointSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSharepointSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharepointSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the firm's SharePoint configuration.","tags":["sharepoint-settings"]}},"/tenant-settings/sharepoint/admin-consent-url":{"get":{"description":"The delegated Sites.ReadWrite.All scope cannot be consented by individual users, so a Global Admin must approve CaseWizard once before anyone can connect.","operationId":"getSharepointAdminConsentUrl","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConsentUrlDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the Microsoft admin-consent URL for this firm.","tags":["sharepoint-settings"]}},"/tenant-settings/sharepoint/admin-consent":{"post":{"description":"Microsoft sends admin consent back to the same redirect URI as the user-connect flow, but with `admin_consent=True&tenant=<tid>` and no authorization code. The web app posts those values here; capturing the tid is what links the firm to its Microsoft organisation.","operationId":"completeSharepointAdminConsent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteAdminConsentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharepointSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Record the Microsoft organization returned by an admin-consent redirect.","tags":["sharepoint-settings"]}},"/tenant-settings/egnyte":{"get":{"operationId":"getEgnyteSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the firm's Egnyte configuration.","tags":["egnyte-settings"]},"put":{"operationId":"updateEgnyteSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEgnyteSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EgnyteSettingsDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the firm's Egnyte configuration.","tags":["egnyte-settings"]}},"/event-types":{"get":{"operationId":"listEventTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EventTypeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List event types.","tags":["events"]},"post":{"operationId":"createEventType","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventTypeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventTypeDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an event type.","tags":["events"]}},"/events":{"get":{"operationId":"listEvents","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"caseId","required":false,"in":"query","schema":{"type":"number"}},{"name":"eventTypeId","required":false,"in":"query","schema":{"type":"number"}},{"name":"eventTypeIds","required":false,"in":"query","description":"Comma-separated event type ids; matching any listed type (additive filter).","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Free-text match on title, location, or note.","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"ISO 8601 lower bound on start time.","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO 8601 upper bound on start time.","schema":{"type":"string"}},{"name":"overlapping","required":false,"in":"query","description":"With from: also return events that start before from but end on or after it, so a calendar range gets every event overlapping it (from to to), not only those starting in it.","schema":{"type":"boolean"}},{"name":"allDayFrom","required":false,"in":"query","description":"First date (yyyy-mm-dd) of a filter by calendar days. All-day events, stored on their date, are matched by it; from and to then apply to timed events only. Use with allDayTo to filter by the user's own days: from and to as the instants their days start and end.","schema":{"type":"string"}},{"name":"allDayTo","required":false,"in":"query","description":"Last date (yyyy-mm-dd, inclusive) of a filter by calendar days; see allDayFrom.","schema":{"type":"string"}},{"name":"reminder","required":false,"in":"query","description":"When true, only events with reminder=true. When false, only events without a reminder.","schema":{"type":"boolean"}},{"name":"sort","required":false,"in":"query","description":"Sort field. Default startTime keeps calendar/agenda chronological.","schema":{"default":"startTime","type":"string","enum":["startTime","lastModificationTime","creationTime"]}},{"name":"order","required":false,"in":"query","description":"Sort direction. Default asc pairs with startTime for calendars.","schema":{"default":"asc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List events (cross-case, date-filterable).","tags":["events"]},"post":{"operationId":"createEvent","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEventDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an event.","tags":["events"]}},"/cases/{caseId}/events":{"get":{"operationId":"listCaseEvents","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"caseId","required":false,"in":"query","schema":{"type":"number"}},{"name":"eventTypeId","required":false,"in":"query","schema":{"type":"number"}},{"name":"eventTypeIds","required":false,"in":"query","description":"Comma-separated event type ids; matching any listed type (additive filter).","schema":{"type":"string"}},{"name":"search","required":false,"in":"query","description":"Free-text match on title, location, or note.","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"ISO 8601 lower bound on start time.","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO 8601 upper bound on start time.","schema":{"type":"string"}},{"name":"overlapping","required":false,"in":"query","description":"With from: also return events that start before from but end on or after it, so a calendar range gets every event overlapping it (from to to), not only those starting in it.","schema":{"type":"boolean"}},{"name":"allDayFrom","required":false,"in":"query","description":"First date (yyyy-mm-dd) of a filter by calendar days. All-day events, stored on their date, are matched by it; from and to then apply to timed events only. Use with allDayTo to filter by the user's own days: from and to as the instants their days start and end.","schema":{"type":"string"}},{"name":"allDayTo","required":false,"in":"query","description":"Last date (yyyy-mm-dd, inclusive) of a filter by calendar days; see allDayFrom.","schema":{"type":"string"}},{"name":"reminder","required":false,"in":"query","description":"When true, only events with reminder=true. When false, only events without a reminder.","schema":{"type":"boolean"}},{"name":"sort","required":false,"in":"query","description":"Sort field. Default startTime keeps calendar/agenda chronological.","schema":{"default":"startTime","type":"string","enum":["startTime","lastModificationTime","creationTime"]}},{"name":"order","required":false,"in":"query","description":"Sort direction. Default asc pairs with startTime for calendars.","schema":{"default":"asc","type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List events for a case.","tags":["events"]}},"/events/{id}":{"get":{"operationId":"getEvent","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an event by id.","tags":["events"]},"patch":{"operationId":"updateEvent","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEventDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an event.","tags":["events"]},"delete":{"operationId":"deleteEvent","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an event.","tags":["events"]}},"/calendar/subscription":{"get":{"operationId":"getCalendarSubscription","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarSubscriptionDto"}}}}},"security":[{"bearer":[]}],"summary":"Get (or create) the current user Outlook/Mac ICS subscribe URL path.","tags":["calendar"]}},"/calendar/feeds/{feedToken}":{"get":{"operationId":"getCalendarFeed","parameters":[{"name":"feedToken","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"iCalendar (text/calendar) body, or text/plain when ?preview is present.","content":{"text/calendar":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}}},"summary":"Public ICS calendar feed for Outlook / Mac Calendar subscribe.","tags":["calendar"]}},"/plaintiffs/{plaintiffId}/injuries":{"get":{"operationId":"listInjuries","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InjuryListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's injuries.","tags":["medical"]},"post":{"operationId":"createInjury","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInjuryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InjuryDto"}}}}},"security":[{"bearer":[]}],"summary":"Add an injury to a plaintiff.","tags":["medical"]}},"/injuries/{id}":{"get":{"operationId":"getInjury","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InjuryDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an injury by id.","tags":["medical"]},"patch":{"operationId":"updateInjury","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInjuryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InjuryDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an injury.","tags":["medical"]},"delete":{"operationId":"deleteInjury","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an injury.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/doctors":{"get":{"operationId":"listDoctors","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoctorListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's doctors.","tags":["medical"]},"post":{"operationId":"createDoctor","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDoctorDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoctorDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a doctor to a plaintiff.","tags":["medical"]}},"/doctors/{id}":{"get":{"operationId":"getDoctor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoctorDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a doctor by id.","tags":["medical"]},"patch":{"operationId":"updateDoctor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDoctorDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DoctorDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a doctor.","tags":["medical"]},"delete":{"operationId":"deleteDoctor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a doctor.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/providers":{"get":{"operationId":"listProviders","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's providers.","tags":["medical"]},"post":{"operationId":"createProvider","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProviderDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a provider to a plaintiff.","tags":["medical"]}},"/providers/{id}":{"get":{"operationId":"getProvider","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a provider by id.","tags":["medical"]},"patch":{"operationId":"updateProvider","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProviderDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a provider.","tags":["medical"]},"delete":{"operationId":"deleteProvider","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a provider.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/medications":{"get":{"operationId":"listMedications","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive substring match on the medication name.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicationListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's medications.","tags":["medical"]},"post":{"operationId":"createMedication","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMedicationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicationDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a medication to a plaintiff.","tags":["medical"]}},"/medications/{id}":{"get":{"operationId":"getMedication","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicationDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a medication by id.","tags":["medical"]},"patch":{"operationId":"updateMedication","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMedicationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicationDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a medication.","tags":["medical"]},"delete":{"operationId":"deleteMedication","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a medication.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/insurance":{"get":{"operationId":"listInsurance","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsuranceListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's insurance coverage.","tags":["medical"]},"post":{"operationId":"createInsurance","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInsuranceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsuranceDto"}}}}},"security":[{"bearer":[]}],"summary":"Add insurance coverage to a plaintiff.","tags":["medical"]}},"/insurance/{id}":{"get":{"operationId":"getInsurance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsuranceDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an insurance record by id.","tags":["medical"]},"patch":{"operationId":"updateInsurance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInsuranceDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InsuranceDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an insurance record.","tags":["medical"]},"delete":{"operationId":"deleteInsurance","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an insurance record.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/subrogors":{"get":{"operationId":"listSubrogors","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubrogorListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's subrogors.","tags":["medical"]},"post":{"operationId":"createSubrogor","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSubrogorDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubrogorDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a subrogor to a plaintiff.","tags":["medical"]}},"/subrogors/{id}":{"get":{"operationId":"getSubrogor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubrogorDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a subrogor by id.","tags":["medical"]},"patch":{"operationId":"updateSubrogor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSubrogorDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubrogorDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a subrogor.","tags":["medical"]},"delete":{"operationId":"deleteSubrogor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a subrogor.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/prior-claims":{"get":{"operationId":"listPriorClaims","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriorClaimListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's prior claims.","tags":["medical"]},"post":{"operationId":"createPriorClaim","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePriorClaimDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriorClaimDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a prior claim to a plaintiff.","tags":["medical"]}},"/prior-claims/{id}":{"get":{"operationId":"getPriorClaim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriorClaimDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a prior claim by id.","tags":["medical"]},"patch":{"operationId":"updatePriorClaim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePriorClaimDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriorClaimDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a prior claim.","tags":["medical"]},"delete":{"operationId":"deletePriorClaim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a prior claim.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/work-history":{"get":{"operationId":"listWorkHistory","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkHistoryListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's work history.","tags":["medical"]},"post":{"operationId":"createWorkHistory","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWorkHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a work history entry to a plaintiff.","tags":["medical"]}},"/work-history/{id}":{"get":{"operationId":"getWorkHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a work history entry by id.","tags":["medical"]},"patch":{"operationId":"updateWorkHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWorkHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a work history entry.","tags":["medical"]},"delete":{"operationId":"deleteWorkHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a work history entry.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/medical-expenses":{"get":{"operationId":"listMedicalExpenses","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalExpenseListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's medical expenses.","tags":["medical"]},"post":{"operationId":"createMedicalExpense","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMedicalExpenseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalExpenseDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a medical expense to a plaintiff.","tags":["medical"]}},"/medical-expenses/{id}":{"get":{"operationId":"getMedicalExpense","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalExpenseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a medical expense by id.","tags":["medical"]},"patch":{"operationId":"updateMedicalExpense","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMedicalExpenseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MedicalExpenseDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a medical expense.","tags":["medical"]},"delete":{"operationId":"deleteMedicalExpense","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a medical expense.","tags":["medical"]}},"/plaintiffs/{plaintiffId}/patient-history":{"get":{"operationId":"listPatientHistory","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientHistoryListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a plaintiff's patient history.","tags":["medical"]},"post":{"operationId":"createPatientHistory","parameters":[{"name":"plaintiffId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePatientHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a patient history note to a plaintiff.","tags":["medical"]}},"/patient-history/{id}":{"get":{"operationId":"getPatientHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a patient history note by id.","tags":["medical"]},"patch":{"operationId":"updatePatientHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePatientHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatientHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a patient history note.","tags":["medical"]},"delete":{"operationId":"deletePatientHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a patient history note.","tags":["medical"]}},"/cases/{caseId}/liens":{"get":{"operationId":"listLiens","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LienListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List liens on a case.","tags":["liens"]},"post":{"operationId":"createLien","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLienDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LienDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a lien to a case.","tags":["liens"]}},"/liens/{id}":{"get":{"operationId":"getLien","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LienDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a lien by id.","tags":["liens"]},"patch":{"operationId":"updateLien","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLienDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LienDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a lien.","tags":["liens"]},"delete":{"operationId":"deleteLien","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a lien.","tags":["liens"]}},"/cases/{caseId}/settlements":{"get":{"operationId":"listSettlements","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List settlements on a case.","tags":["settlements"]},"post":{"operationId":"createSettlement","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSettlementDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a settlement to a case.","tags":["settlements"]}},"/settlements/{id}":{"get":{"operationId":"getSettlement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a settlement by id.","tags":["settlements"]},"patch":{"operationId":"updateSettlement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettlementDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettlementDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a settlement.","tags":["settlements"]},"delete":{"operationId":"deleteSettlement","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a settlement.","tags":["settlements"]}},"/cases/{caseId}/criminal-charges":{"get":{"operationId":"listCriminalCharges","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriminalChargeListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List criminal charges on a case.","tags":["criminal-charges"]},"post":{"operationId":"createCriminalCharge","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCriminalChargeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriminalChargeDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a criminal charge to a case.","tags":["criminal-charges"]}},"/criminal-charges/{id}":{"get":{"operationId":"getCriminalCharge","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriminalChargeDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a criminal charge by id.","tags":["criminal-charges"]},"patch":{"operationId":"updateCriminalCharge","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCriminalChargeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriminalChargeDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a criminal charge.","tags":["criminal-charges"]},"delete":{"operationId":"deleteCriminalCharge","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a criminal charge.","tags":["criminal-charges"]}},"/cases/{caseId}/victims":{"get":{"operationId":"listVictims","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VictimListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List victims on a case.","tags":["victims"]},"post":{"operationId":"createVictim","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVictimDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VictimDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a victim to a case.","tags":["victims"]}},"/victims/{id}":{"get":{"operationId":"getVictim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VictimDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a victim by id.","tags":["victims"]},"patch":{"operationId":"updateVictim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVictimDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VictimDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a victim.","tags":["victims"]},"delete":{"operationId":"deleteVictim","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a victim.","tags":["victims"]}},"/cases/{caseId}/officers":{"get":{"operationId":"listOfficers","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoliceOfficerListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List police officers on a case.","tags":["officers"]},"post":{"operationId":"createOfficer","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePoliceOfficerDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoliceOfficerDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a police officer to a case.","tags":["officers"]}},"/officers/{id}":{"get":{"operationId":"getOfficer","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoliceOfficerDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a police officer by id.","tags":["officers"]},"patch":{"operationId":"updateOfficer","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePoliceOfficerDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PoliceOfficerDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a police officer.","tags":["officers"]},"delete":{"operationId":"deleteOfficer","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a police officer.","tags":["officers"]}},"/cases/{caseId}/prosecutors":{"get":{"operationId":"listProsecutors","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProsecutorListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List prosecutors on a case.","tags":["prosecutors"]},"post":{"operationId":"createProsecutor","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateProsecutorDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProsecutorDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a prosecutor to a case.","tags":["prosecutors"]}},"/prosecutors/{id}":{"get":{"operationId":"getProsecutor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProsecutorDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a prosecutor by id.","tags":["prosecutors"]},"patch":{"operationId":"updateProsecutor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateProsecutorDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProsecutorDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a prosecutor.","tags":["prosecutors"]},"delete":{"operationId":"deleteProsecutor","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a prosecutor.","tags":["prosecutors"]}},"/cases/{caseId}/bondsmen":{"get":{"operationId":"listBondsmen","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BondsmanListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List bondsmen on a case.","tags":["bondsmen"]},"post":{"operationId":"createBondsman","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBondsmanDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BondsmanDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a bondsman to a case.","tags":["bondsmen"]}},"/bondsmen/{id}":{"get":{"operationId":"getBondsman","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BondsmanDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a bondsman by id.","tags":["bondsmen"]},"patch":{"operationId":"updateBondsman","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBondsmanDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BondsmanDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a bondsman.","tags":["bondsmen"]},"delete":{"operationId":"deleteBondsman","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a bondsman.","tags":["bondsmen"]}},"/cases/{caseId}/roll-call-locations":{"get":{"operationId":"listRollCallLocations","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollCallLocationListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List roll call locations on a case.","tags":["roll-call-locations"]},"post":{"operationId":"createRollCallLocation","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRollCallLocationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollCallLocationDto"}}}}},"security":[{"bearer":[]}],"summary":"Link a roll call location (person or organization) to a case.","tags":["roll-call-locations"]}},"/roll-call-locations/{id}":{"get":{"operationId":"getRollCallLocation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollCallLocationDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a roll call location by id.","tags":["roll-call-locations"]},"patch":{"operationId":"updateRollCallLocation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRollCallLocationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollCallLocationDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a roll call location.","tags":["roll-call-locations"]},"delete":{"operationId":"deleteRollCallLocation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a roll call location.","tags":["roll-call-locations"]}},"/cases/{caseId}/history-requests":{"get":{"operationId":"listHistoryRequests","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryRequestListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List records requests on a case.","tags":["history-requests"]},"post":{"operationId":"createHistoryRequest","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateHistoryRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a records request to a case.","tags":["history-requests"]}},"/history-requests/{id}":{"get":{"operationId":"getHistoryRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a records request by id.","tags":["history-requests"]},"patch":{"operationId":"updateHistoryRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHistoryRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a records request.","tags":["history-requests"]},"delete":{"operationId":"deleteHistoryRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a records request.","tags":["history-requests"]}},"/history-requests/{id}/history":{"get":{"operationId":"listHistoryRequestHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseHistoryListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a records request's inline history entries.","tags":["history-requests"]},"post":{"operationId":"createHistoryRequestHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCaseHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Add an entry to a records request's inline history.","tags":["history-requests"]}},"/cases/{caseId}/case-histories":{"get":{"operationId":"listCaseHistories","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseHistoryListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List history entries on a case.","tags":["case-histories"]},"post":{"operationId":"createCaseHistory","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCaseHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a history entry to a case.","tags":["case-histories"]}},"/case-histories/{id}":{"get":{"operationId":"getCaseHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a history entry by id.","tags":["case-histories"]},"patch":{"operationId":"updateCaseHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCaseHistoryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseHistoryDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a history entry.","tags":["case-histories"]},"delete":{"operationId":"deleteCaseHistory","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a history entry.","tags":["case-histories"]}},"/lookups/states":{"get":{"operationId":"listStates","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StateDto"}}}}}},"security":[{"bearer":[]}],"summary":"List states.","tags":["lookups"]}},"/lookups/user-classifications":{"get":{"operationId":"listUserClassifications","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CodeLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES timekeeper classifications (Partner, Associate, ...).","tags":["lookups"]}},"/lookups/offer-types":{"get":{"operationId":"listOfferTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List settlement offer types.","tags":["lookups"]}},"/lookups/genders":{"get":{"operationId":"listGenders","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List genders.","tags":["lookups"]}},"/lookups/races":{"get":{"operationId":"listRaces","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List races.","tags":["lookups"]}},"/lookups/marital-statuses":{"get":{"operationId":"listMaritalStatuses","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List marital statuses.","tags":["lookups"]}},"/lookups/relationships":{"get":{"operationId":"listRelationships","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List relationships.","tags":["lookups"]}},"/lookups/person-roles":{"get":{"operationId":"listPersonRoles","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List person roles.","tags":["lookups"]}},"/lookups/person-types":{"get":{"operationId":"listPersonTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List person types.","tags":["lookups"]}},"/lookups/organization-types":{"get":{"operationId":"listOrganizationTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List organization types.","tags":["lookups"]}},"/lookups/injury-types":{"get":{"operationId":"listInjuryTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List injury types.","tags":["lookups"]}},"/lookups/doctor-specialties":{"get":{"operationId":"listDoctorSpecialties","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List doctor specialties.","tags":["lookups"]}},"/lookups/lien-types":{"get":{"operationId":"listLienTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List lien types.","tags":["lookups"]}},"/lookups/insurance-types":{"get":{"operationId":"listInsuranceTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List insurance types.","tags":["lookups"]}},"/lookups/medication-index":{"get":{"operationId":"listMedicationIndex","parameters":[{"name":"search","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LookupItemDto"}}}}}},"security":[{"bearer":[]}],"summary":"List the medication index catalog.","tags":["lookups"]}},"/lookups/icd":{"get":{"operationId":"listIcdCodes","parameters":[{"name":"search","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CodeLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"Search the ICD diagnosis-code catalog.","tags":["lookups"]}},"/lookups/criminal-charge-index":{"get":{"description":"Per tenant, like legacy CriminalChargeIndex (Charge, Penalty, StatuteSection). Rows are added by creating a criminal charge with newIndex. Matches charge or statute section.","operationId":"listCriminalChargeIndex","parameters":[{"name":"search","required":false,"in":"query","description":"Matches charge or statute section (case-insensitive).","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CriminalChargeIndexDto"}}}}}},"security":[{"bearer":[]}],"summary":"Search the tenant's criminal charge index.","tags":["lookups"]}},"/time-entries":{"get":{"operationId":"listTimeEntries","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on description.","schema":{"type":"string"}},{"name":"caseId","required":false,"in":"query","schema":{"type":"number"}},{"name":"assignedToUserId","required":false,"in":"query","description":"Timekeeper filter. Callers without Billing.View only see their own time (legacy GetTimeEntries), so for them this defaults to, and must be, the acting user.","schema":{"type":"string"}},{"name":"timeSheetId","required":false,"in":"query","schema":{"type":"number"}},{"name":"preBillId","required":false,"in":"query","description":"Filter to the time entries attached to a pre-bill.","schema":{"type":"number"}},{"name":"invoiceId","required":false,"in":"query","description":"Filter to the time entries billed on an invoice.","schema":{"type":"number"}},{"name":"billingStatusId","required":false,"in":"query","schema":{"type":"number"}},{"name":"timeEntryStageId","required":false,"in":"query","description":"Workflow stage filter (Open, Submitted, ...).","schema":{"type":"number"}},{"name":"running","required":false,"in":"query","description":"true = only running timers (no endDate). Query string \"false\"/\"0\" is false.","schema":{"type":"boolean"}},{"name":"from","required":false,"in":"query","description":"ISO 8601 lower bound on startDate.","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"ISO 8601 upper bound on startDate.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeEntryListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List time entries (paginated).","tags":["time"]},"post":{"operationId":"createTimeEntry","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTimeEntryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeEntryDto"}}}},"409":{"description":"The time sheet for the entry's week (or, for an update, the week it moves to) is Submitted or Approved and approval is not bypassed."}},"security":[{"bearer":[]}],"summary":"Create a time entry.","tags":["time"]}},"/time-entries/timer/start":{"post":{"operationId":"startTimer","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartTimerDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeEntryDto"}}}},"409":{"description":"The time sheet for the entry's week (or, for an update, the week it moves to) is Submitted or Approved and approval is not bypassed."}},"security":[{"bearer":[]}],"summary":"Start a running timer.","tags":["time"]}},"/time-entries/{id}/timer/stop":{"post":{"operationId":"stopTimer","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeEntryDto"}}}}},"security":[{"bearer":[]}],"summary":"Stop a running timer and derive hours.","tags":["time"]}},"/time-entries/{id}":{"get":{"operationId":"getTimeEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeEntryDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a time entry by id.","tags":["time"]},"patch":{"operationId":"updateTimeEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTimeEntryDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeEntryDto"}}}},"409":{"description":"The time sheet for the entry's week (or, for an update, the week it moves to) is Submitted or Approved and approval is not bypassed."}},"security":[{"bearer":[]}],"summary":"Update a time entry.","tags":["time"]},"delete":{"operationId":"deleteTimeEntry","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"409":{"description":"The time sheet for the entry's week (or, for an update, the week it moves to) is Submitted or Approved and approval is not bypassed."}},"security":[{"bearer":[]}],"summary":"Soft-delete a time entry.","tags":["time"]}},"/timesheets/mine":{"get":{"description":"Derived from the caller's time entries (held time and manual-invoice lines excluded). A week with no time sheet row is Open.","operationId":"listMyTimesheets","parameters":[{"name":"from","required":false,"in":"query","description":"Only weeks with time on or after this date (YYYY-MM-DD, UTC).","schema":{"example":"2026-01-01","type":"string"}},{"name":"to","required":false,"in":"query","description":"Only weeks with time on or before this date (YYYY-MM-DD, inclusive, UTC).","schema":{"example":"2026-12-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekListDto"}}}}},"security":[{"bearer":[]}],"summary":"The acting user's time sheet weeks, newest first.","tags":["timesheets"]}},"/timesheets":{"get":{"description":"Derived weeks sorted by timekeeper, then year and week descending (legacy GetAllTimeSheets).","operationId":"listTimesheets","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"timekeeperId","required":false,"in":"query","description":"Timekeeper (bigint user id).","schema":{"type":"string"}},{"name":"assignedToUserId","required":false,"in":"query","description":"Deprecated alias of timekeeperId.","deprecated":true,"schema":{"type":"string"}},{"name":"from","required":false,"in":"query","description":"Only weeks with time on or after this date (YYYY-MM-DD, UTC).","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","description":"Only weeks with time on or before this date (YYYY-MM-DD, inclusive, UTC).","schema":{"type":"string"}},{"name":"year","required":false,"in":"query","description":"Filter by year.","schema":{"type":"number"}},{"name":"week","required":false,"in":"query","description":"Filter by week. en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","schema":{"type":"number"}},{"name":"stage","required":false,"in":"query","description":"Filter by stage name. A week with no time sheet row is Open.","schema":{"type":"string","enum":["Open","Submitted","Rejected","Approved"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Every timekeeper's time sheet weeks (approvers).","tags":["timesheets"]},"post":{"deprecated":true,"description":"Deprecated: time sheets are derived weeks; use the /timesheets/{userId}/{year}/{week} endpoints. Will be removed in a later release.","operationId":"createTimesheet","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTimeSheetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a timesheet (Open).","tags":["timesheets"]}},"/timesheets/{userId}/{year}/{week}":{"get":{"description":"Timekeepers can open their own weeks; approvers can open anyone's.","operationId":"getTimesheetWeek","parameters":[{"name":"userId","required":true,"in":"path","description":"Timekeeper (bigint user id).","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"example":2026,"type":"number"}},{"name":"week","required":true,"in":"path","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","schema":{"example":23,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"One timekeeper's week with its days and entries.","tags":["timesheets"]}},"/timesheets/{userId}/{year}/{week}/submit":{"post":{"description":"Allowed from Open or Rejected. Stamps the week's time and moves it to Submitted. The timekeeper submits their own week; approvers may submit on someone's behalf.","operationId":"submitTimesheetWeek","parameters":[{"name":"userId","required":true,"in":"path","description":"Timekeeper (bigint user id).","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"example":2026,"type":"number"}},{"name":"week","required":true,"in":"path","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","schema":{"example":23,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekDetailDto"}}}},"409":{"description":"The week is already Submitted or Approved."}},"security":[{"bearer":[]}],"summary":"Submit a week for approval.","tags":["timesheets"]}},"/timesheets/{userId}/{year}/{week}/approve":{"post":{"description":"Approvers may approve their own week (legacy).","operationId":"approveTimesheetWeek","parameters":[{"name":"userId","required":true,"in":"path","description":"Timekeeper (bigint user id).","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"example":2026,"type":"number"}},{"name":"week","required":true,"in":"path","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","schema":{"example":23,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekDetailDto"}}}},"409":{"description":"The week is not Submitted."}},"security":[{"bearer":[]}],"summary":"Approve a submitted week.","tags":["timesheets"]}},"/timesheets/{userId}/{year}/{week}/reject":{"post":{"operationId":"rejectTimesheetWeek","parameters":[{"name":"userId","required":true,"in":"path","description":"Timekeeper (bigint user id).","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"example":2026,"type":"number"}},{"name":"week","required":true,"in":"path","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","schema":{"example":23,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekDetailDto"}}}},"409":{"description":"The week is not Submitted."}},"security":[{"bearer":[]}],"summary":"Reject a submitted week.","tags":["timesheets"]}},"/timesheets/{userId}/{year}/{week}/undo-approval":{"post":{"description":"Only when nothing in the week is on a pre-bill or invoice.","operationId":"undoTimesheetWeekApproval","parameters":[{"name":"userId","required":true,"in":"path","description":"Timekeeper (bigint user id).","schema":{"type":"string"}},{"name":"year","required":true,"in":"path","schema":{"example":2026,"type":"number"}},{"name":"week","required":true,"in":"path","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","schema":{"example":23,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetWeekDetailDto"}}}},"409":{"description":"The week is not Approved, or some of its time is billed."}},"security":[{"bearer":[]}],"summary":"Undo an approval (moves the week to Rejected).","tags":["timesheets"]}},"/timesheets/{id}":{"get":{"operationId":"getTimesheet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a timesheet row by id.","tags":["timesheets"]},"patch":{"deprecated":true,"description":"Deprecated: time sheets are derived weeks; use the /timesheets/{userId}/{year}/{week} endpoints. Will be removed in a later release.","operationId":"updateTimesheet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTimeSheetDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a timesheet.","tags":["timesheets"]},"delete":{"deprecated":true,"description":"Deprecated: time sheets are derived weeks; use the /timesheets/{userId}/{year}/{week} endpoints. Will be removed in a later release.","operationId":"deleteTimesheet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a timesheet.","tags":["timesheets"]}},"/timesheets/{id}/submit":{"post":{"deprecated":true,"description":"Deprecated: time sheets are derived weeks; use the /timesheets/{userId}/{year}/{week} endpoints. Will be removed in a later release.","operationId":"submitTimesheet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetDto"}}}}},"security":[{"bearer":[]}],"summary":"Submit a timesheet for approval.","tags":["timesheets"]}},"/timesheets/{id}/approve":{"post":{"deprecated":true,"description":"Deprecated: time sheets are derived weeks; use the /timesheets/{userId}/{year}/{week} endpoints. Will be removed in a later release.","operationId":"approveTimesheet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetDto"}}}}},"security":[{"bearer":[]}],"summary":"Approve a submitted timesheet.","tags":["timesheets"]}},"/timesheets/{id}/reject":{"post":{"deprecated":true,"description":"Deprecated: time sheets are derived weeks; use the /timesheets/{userId}/{year}/{week} endpoints. Will be removed in a later release.","operationId":"rejectTimesheet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeSheetDto"}}}}},"security":[{"bearer":[]}],"summary":"Reject a submitted timesheet.","tags":["timesheets"]}},"/billing/time-entry-stages":{"get":{"operationId":"listTimeEntryStages","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List time entry stages.","tags":["billing-lookups"]}},"/billing/time-sheet-stages":{"get":{"operationId":"listTimeSheetStages","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List timesheet stages.","tags":["billing-lookups"]}},"/billing/invoice-stages":{"get":{"operationId":"listInvoiceStages","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List invoice stages.","tags":["billing-lookups"]}},"/billing/rate-types":{"get":{"operationId":"listRateTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DescribedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List rate types.","tags":["billing-lookups"]}},"/billing/billing-statuses":{"get":{"operationId":"listBillingStatuses","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DescribedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List billing statuses.","tags":["billing-lookups"]}},"/billing/billing-methods":{"get":{"operationId":"listBillingMethods","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DescribedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List billing methods.","tags":["billing-lookups"]}},"/billing/ledes/code-sets":{"get":{"operationId":"listLedesCodeSets","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES code sets.","tags":["billing-lookups"]}},"/billing/ledes/phases":{"get":{"operationId":"listLedesPhases","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES phases.","tags":["billing-lookups"]}},"/billing/ledes/activities":{"get":{"operationId":"listLedesActivities","parameters":[{"name":"search","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LedesCodeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES activity codes.","tags":["billing-lookups"]}},"/billing/ledes/tasks":{"get":{"operationId":"listLedesTasks","parameters":[{"name":"search","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LedesCodeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES task codes.","tags":["billing-lookups"]}},"/billing/ledes/expense-sets":{"get":{"operationId":"listLedesExpenseSets","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES expense sets.","tags":["billing-lookups"]}},"/billing/ledes/expenses":{"get":{"operationId":"listLedesExpenses","parameters":[{"name":"search","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LedesCodeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List LEDES expense codes.","tags":["billing-lookups"]}},"/billing/billing-codes":{"get":{"operationId":"listBillingCodes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BillingCodeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List billing codes for the tenant.","tags":["billing-lookups"]}},"/billing/abbreviations":{"get":{"operationId":"listBillingAbbreviations","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AbbreviationDto"}}}}}},"security":[{"bearer":[]}],"summary":"List abbreviations for the tenant.","tags":["billing-lookups"]}},"/billing/fee-types":{"get":{"operationId":"listFeeTypes","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/FeeTypeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List fee types for the tenant.","tags":["billing-lookups"]}},"/billing/invoice-terms":{"get":{"operationId":"listInvoiceTerms","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceTermsDto"}}}}}},"security":[{"bearer":[]}],"summary":"List invoice terms for the tenant.","tags":["billing-lookups"]}},"/billing-entities":{"get":{"operationId":"listBillingEntities","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on name.","schema":{"type":"string"}},{"name":"isActive","required":false,"in":"query","schema":{"type":"boolean"}},{"name":"parentBillingEntityId","required":false,"in":"query","description":"Filter to children of this parent.","schema":{"type":"number"}},{"name":"rateTypeId","required":false,"in":"query","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List billing entities (paginated).","tags":["billing-entities"]},"post":{"operationId":"createBillingEntity","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillingEntityDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a billing entity.","tags":["billing-entities"]}},"/billing-entities/{id}":{"get":{"operationId":"getBillingEntity","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a billing entity by id.","tags":["billing-entities"]},"patch":{"operationId":"updateBillingEntity","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillingEntityDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a billing entity.","tags":["billing-entities"]},"delete":{"operationId":"deleteBillingEntity","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":"Deleted."},"409":{"description":"Still used by cases, payments, statements or child billing entities (code BILLING_ENTITY_IN_USE)."}},"security":[{"bearer":[]}],"summary":"Soft-delete a billing entity. Refused with 409 BILLING_ENTITY_IN_USE while still used.","tags":["billing-entities"]}},"/billing-entities/{id}/detail":{"get":{"operationId":"getBillingEntityDetail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a billing entity with its cases and invoices.","tags":["billing-entities"]}},"/billing-entities/{id}/transactions":{"get":{"operationId":"listBillingEntityTransactions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"type","required":false,"in":"query","description":"Only this kind of line. Balances are still those of the whole history, not of the filtered lines.","schema":{"type":"string","enum":["invoice","payment","invoice_payment","statement"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityTransactionListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"The billing entity's history, newest first: invoices, payments received (with their invoice allocations and retainer movement), payments on a single invoice, and statements, each with the balances after it.","tags":["billing-entities"]}},"/billing-entities/{id}/timekeeper-rates/{timeKeeperId}":{"put":{"operationId":"setBillingEntityTimeKeeperRate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"timeKeeperId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetBillingEntityRateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityTimeKeeperRateDto"}}}}}},"security":[{"bearer":[]}],"summary":"Set (or clear with null) a timekeeper rate on the entity; returns the full grid.","tags":["billing-entities"]}},"/billing-entities/{id}/task-rates/{ledesTaskId}":{"put":{"operationId":"setBillingEntityTaskRate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"ledesTaskId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetBillingEntityRateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityTaskRateDto"}}}}}},"security":[{"bearer":[]}],"summary":"Set (or clear with null) a LEDES task rate on the entity; returns the full grid.","tags":["billing-entities"]}},"/payments":{"get":{"operationId":"listPayments","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"invoiceId","required":false,"in":"query","description":"Filter by invoice.","schema":{"type":"number"}},{"name":"billingEntityPaymentId","required":false,"in":"query","description":"Filter by parent billing-entity payment.","schema":{"type":"number"}},{"name":"search","required":false,"in":"query","description":"Case-insensitive match on the billing entity name or check number.","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"Only payments dated on/after this date.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"Only payments dated on/before this date (inclusive).","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List payments (paginated).","tags":["payments"]},"post":{"operationId":"createPayment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDto"}}}}},"security":[{"bearer":[]}],"summary":"Record a single payment against an invoice.","tags":["payments"]}},"/payments/received":{"get":{"operationId":"listPaymentsReceived","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive match on the billing entity name or check number.","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","description":"Only payments dated on/after this date.","schema":{"type":"string"}},{"name":"endDate","required":false,"in":"query","description":"Only payments dated on/before this date (inclusive).","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentReceivedListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List payments received (paginated): each billing entity payment as a whole, and each payment recorded on one invoice without one. Oldest first, then by billing entity name and amount.","tags":["payments"]}},"/payments/{id}":{"get":{"operationId":"getPayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a payment by id.","tags":["payments"]},"patch":{"operationId":"updatePayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePaymentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a payment.","tags":["payments"]},"delete":{"description":"A payment that is an invoice's share of a billing-entity payment is deleted with that whole payment: every invoice share and its retainer credit or debit (as DELETE /billing-entity-payments/{id}).","operationId":"deletePayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a payment and reopen its invoice.","tags":["payments"]}},"/billing-entities/{id}/payment-allocation":{"get":{"operationId":"getPaymentAllocation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentAllocationDto"}}}}},"security":[{"bearer":[]}],"summary":"Outstanding balance per invoice for a billing entity, plus retainer balance.","tags":["payments"]}},"/billing-entities/{id}/payments":{"post":{"operationId":"createBillingEntityPayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillingEntityPaymentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityPaymentDto"}}}}},"security":[{"bearer":[]}],"summary":"Record a billing-entity payment allocated across invoices, with retainer movement.","tags":["payments"]}},"/billing-entity-payments/{id}":{"get":{"operationId":"getBillingEntityPayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingEntityPaymentDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a billing-entity payment with its retainer and child payments.","tags":["payments"]},"delete":{"operationId":"deleteBillingEntityPayment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a billing-entity payment, its child payments, and reopen their invoices.","tags":["payments"]}},"/retainers":{"get":{"operationId":"listRetainers","parameters":[{"name":"billingEntityId","required":true,"in":"query","description":"Billing entity to report retainers for.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RetainerLedgerEntryDto"}}}}}},"security":[{"bearer":[]}],"summary":"List retainer movements for a billing entity, each with the payment and invoices it went to.","tags":["retainers"]}},"/retainers/balance":{"get":{"operationId":"getRetainerBalance","parameters":[{"name":"billingEntityId","required":true,"in":"query","description":"Billing entity to report retainers for.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetainerBalanceDto"}}}}},"security":[{"bearer":[]}],"summary":"Retainer balance (credits minus debits) for a billing entity.","tags":["retainers"]}},"/billables":{"get":{"operationId":"listBillables","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Match case style or billing entity name.","schema":{"type":"string"}},{"name":"startDate","required":false,"in":"query","schema":{"example":"2026-08-01","type":"string"}},{"name":"endDate","required":false,"in":"query","schema":{"example":"2026-08-31","type":"string"}},{"name":"attorneyOfRecordId","required":false,"in":"query","description":"Case.attorneyOfRecordUserId","schema":{"type":"number"}},{"name":"primaryAttorneyId","required":false,"in":"query","description":"Case.assignedToUserId (primary attorney).","schema":{"type":"number"}},{"name":"caseTypeId","required":false,"in":"query","schema":{"type":"number"}},{"name":"includeUnapproved","required":false,"in":"query","description":"Include time that is not yet Approved even when the tenant requires approval. Unapproved time is always included when the tenant billing setting bypassTimeEntryApproval is on (the legacy default).","schema":{"default":false,"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillableListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List unbilled billable activity grouped by case and billing entity (legacy GetBillables).","tags":["billables"]}},"/expenses":{"get":{"operationId":"listExpenses","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"caseId","required":false,"in":"query","description":"Filter by case.","schema":{"type":"number"}},{"name":"invoiceId","required":false,"in":"query","description":"Filter by invoice.","schema":{"type":"number"}},{"name":"billable","required":false,"in":"query","description":"Filter to billable expenses only.","schema":{"type":"boolean"}},{"name":"uninvoiced","required":false,"in":"query","description":"When true, only expenses not yet attached to an invoice.","schema":{"type":"boolean"}},{"name":"from","required":false,"in":"query","description":"Expense date on/after (yyyy-mm-dd).","schema":{"example":"2026-05-01","type":"string"}},{"name":"to","required":false,"in":"query","description":"Expense date on/before (yyyy-mm-dd).","schema":{"example":"2026-05-31","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List expenses (paginated).","tags":["expenses"]},"post":{"operationId":"createExpense","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateExpenseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an expense line.","tags":["expenses"]}},"/expenses/{id}":{"get":{"operationId":"getExpense","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an expense by id.","tags":["expenses"]},"patch":{"operationId":"updateExpense","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateExpenseDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpenseDto"}}}},"409":{"description":"The expense is invoiced and read-only."}},"security":[{"bearer":[]}],"summary":"Update an expense line.","tags":["expenses"]},"delete":{"operationId":"deleteExpense","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"409":{"description":"The expense is invoiced and read-only."}},"security":[{"bearer":[]}],"summary":"Soft-delete an expense line.","tags":["expenses"]}},"/ledes/export":{"get":{"operationId":"exportLedes","parameters":[{"name":"invoiceId","required":true,"in":"query","description":"Invoice to export in LEDES 1998B format.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LedesExportDto"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LedesProblemDto"}}}}},"security":[{"bearer":[]}],"summary":"Export an invoice as a LEDES 1998B e-billing file.","tags":["ledes"]}},"/document-templates":{"get":{"operationId":"listDocumentTemplates","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentTemplateDto"}}}}}},"security":[{"bearer":[]}],"summary":"List mail-merge templates.","tags":["document-templates"]},"post":{"operationId":"createDocumentTemplate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDocumentTemplateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentTemplateDto"}}}}},"security":[{"bearer":[]}],"summary":"Register a merge template.","tags":["document-templates"]}},"/document-templates/{id}":{"get":{"operationId":"getDocumentTemplate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentTemplateDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a merge template.","tags":["document-templates"]},"patch":{"operationId":"updateDocumentTemplate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDocumentTemplateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentTemplateDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a merge template.","tags":["document-templates"]},"delete":{"operationId":"deleteDocumentTemplate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a merge template.","tags":["document-templates"]}},"/documents/merge-fields":{"get":{"operationId":"getMergeFields","parameters":[{"name":"caseTypeId","required":false,"in":"query","description":"Only include custom detail groups for this case type (plus groups that apply to every case type).","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeFieldsDto"}}}}},"security":[{"bearer":[]}],"summary":"List the merge tokens available to mail-merge templates, optionally for one case type.","tags":["documents"]}},"/documents/merge":{"post":{"operationId":"createDocumentMerge","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMergeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Merge a template against a case and return the SharePoint URL when complete.","tags":["documents"]}},"/documents/merge/validate":{"post":{"operationId":"validateDocumentMerge","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMergeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MergeValidationResultDto"}}}}},"security":[{"bearer":[]}],"summary":"Check which legacy merge fields are filled for a template and case.","tags":["documents"]}},"/documents/merges":{"get":{"operationId":"listDocumentMerges","parameters":[{"name":"caseId","required":false,"in":"query","description":"Filter merges by case.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DocumentMergeDto"}}}}}},"security":[{"bearer":[]}],"summary":"List document merges.","tags":["documents"]}},"/documents/merges/{id}":{"get":{"operationId":"getDocumentMerge","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentMergeDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a document merge record.","tags":["documents"]}},"/cases/{caseId}/merge-data":{"get":{"operationId":"getCaseMergeData","parameters":[{"name":"caseId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CaseMergeDataDto"}}}}},"security":[{"bearer":[]}],"summary":"Merge data for a case as token to value JSON (Word add-in live insertion).","tags":["documents"]}},"/exports/{entity}":{"post":{"operationId":"createExport","parameters":[{"name":"entity","required":true,"in":"path","description":"users | cases | events | time | invoices | payments | audit-log","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Enqueue an Excel export of an entity; poll the returned job for the .xlsx.","tags":["exports"]}},"/invoices/{id}/pdf":{"post":{"operationId":"renderInvoicePdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfJobEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Render an invoice to PDF (enqueues a job; poll for the file). Moves the invoice to Printed unless it is Paid or Partial Payment.","tags":["billing-pdf"]}},"/statements/{statementId}/pdf":{"post":{"operationId":"renderStatementPdf","parameters":[{"name":"statementId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfJobEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Render a saved statement to PDF (enqueues a job). Prints the statement's own date, period and stored totals.","tags":["billing-pdf"]}},"/cases/{id}/statement/pdf":{"post":{"operationId":"renderCaseStatementPdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"asOf","required":false,"in":"query","description":"As-of date for the statement and its aging (defaults to now). Aging is measured in whole days past each invoice due date (the invoice date when there is no due date).","schema":{"example":"2026-06-30","type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfJobEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Render the case's live statement to PDF (enqueues a job): invoices with a balance above zero, total balance due and aging.","tags":["billing-pdf"]}},"/invoices/{id}/ledes":{"post":{"operationId":"enqueueInvoiceLedes","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfJobEnqueuedDto"}}}},"400":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LedesProblemDto"}}}}},"security":[{"bearer":[]}],"summary":"Generate the LEDES 1998B file for an invoice as a downloadable job. The invoice is validated first; a missing Matter Id, Internal or Client Matter Id (or its value), primary user, or timekeeper classification returns 400 with `title` and `detail` and no job is enqueued.","tags":["billing-pdf"]}},"/pre-bills/download":{"post":{"operationId":"downloadPreBills","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadPreBillsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfJobEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Batch-download pre-bill worksheets as one PDF (enqueues a job).","tags":["billing-pdf"]}},"/invoices/print-batch":{"post":{"operationId":"printInvoiceBatch","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrintBatchInvoicesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PdfJobEnqueuedDto"}}}}},"security":[{"bearer":[]}],"summary":"Print multiple invoices as one PDF and move them to Printed (Paid and Partial Payment invoices keep their stage).","tags":["billing-pdf"]}},"/api-keys":{"get":{"operationId":"listApiKeys","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ApiKeyDto"}}}}}},"security":[{"bearer":[]}],"summary":"List the tenant API keys.","tags":["api-keys"]},"post":{"operationId":"createApiKey","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedApiKeyDto"}}}}},"security":[{"bearer":[]}],"summary":"Issue a new API key (secret shown once).","tags":["api-keys"]}},"/api-keys/{id}/rotate":{"post":{"operationId":"rotateApiKey","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedApiKeyDto"}}}}},"security":[{"bearer":[]}],"summary":"Rotate a key (new secret shown once).","tags":["api-keys"]}},"/api-keys/{id}/revoke":{"post":{"operationId":"revokeApiKey","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyDto"}}}}},"security":[{"bearer":[]}],"summary":"Revoke a key without deleting it.","tags":["api-keys"]}},"/api-keys/{id}":{"delete":{"operationId":"deleteApiKey","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a key.","tags":["api-keys"]}},"/oauth-clients":{"get":{"operationId":"listOAuthClients","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OAuthClientDto"}}}}}},"security":[{"bearer":[]}],"summary":"List the tenant OAuth clients.","tags":["oauth-clients"]},"post":{"operationId":"createOAuthClient","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOAuthClientDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedOAuthClientDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an OAuth client (secret shown once).","tags":["oauth-clients"]}},"/oauth-clients/{id}/revoke":{"post":{"operationId":"revokeOAuthClient","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthClientDto"}}}}},"security":[{"bearer":[]}],"summary":"Revoke an OAuth client.","tags":["oauth-clients"]}},"/oauth-clients/{id}":{"delete":{"operationId":"deleteOAuthClient","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an OAuth client.","tags":["oauth-clients"]}},"/abbreviations":{"get":{"operationId":"listAbbreviations","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on code or phrase.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbbreviationListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List abbreviations.","tags":["abbreviations"]},"post":{"operationId":"createAbbreviation","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAbbreviationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbbreviationDto"}}}},"409":{"description":"Another abbreviation already uses this code (case-insensitive)."}},"security":[{"bearer":[]}],"summary":"Create an abbreviation.","tags":["abbreviations"]}},"/abbreviations/{id}":{"get":{"operationId":"getAbbreviation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbbreviationDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an abbreviation by id.","tags":["abbreviations"]},"patch":{"operationId":"updateAbbreviation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAbbreviationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbbreviationDto"}}}},"409":{"description":"Another abbreviation already uses this code (case-insensitive)."}},"security":[{"bearer":[]}],"summary":"Update an abbreviation.","tags":["abbreviations"]},"delete":{"operationId":"deleteAbbreviation","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an abbreviation.","tags":["abbreviations"]}},"/roles":{"get":{"operationId":"listRoles","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on name.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List roles with their granted permissions.","tags":["roles"]},"post":{"operationId":"createRole","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoleDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a role.","tags":["roles"]}},"/roles/{id}":{"get":{"operationId":"getRole","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a role by id.","tags":["roles"]},"patch":{"operationId":"updateRole","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a role (name and/or permission set).","tags":["roles"]},"delete":{"operationId":"deleteRole","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a role (static roles are protected).","tags":["roles"]}},"/permissions":{"get":{"operationId":"listPermissions","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PermissionDto"}}}}}},"security":[{"bearer":[]}],"summary":"List the global permission catalog.","tags":["permissions"]}},"/users":{"get":{"operationId":"listUsers","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on user name or email.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List users with assigned roles.","tags":["users"]},"post":{"operationId":"createUser","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a user.","tags":["users"]}},"/users/{id}":{"get":{"operationId":"getUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a user by id.","tags":["users"]},"patch":{"operationId":"updateUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a user (profile, active flag, password, roles).","tags":["users"]},"delete":{"operationId":"deleteUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a user.","tags":["users"]}},"/users/{id}/avatar":{"get":{"operationId":"getUserAvatar","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AvatarDto"}}}}},"security":[{"bearer":[]}],"summary":"A user's profile picture (stored in object storage; returned as a data URL).","tags":["users"]}},"/users/{id}/impersonate":{"post":{"operationId":"impersonateUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}},{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"security":[{"bearer":[]}],"summary":"Log in as another active user of this firm (Users.Impersonate). Returns a session for that user; POST /v1/auth/exit-impersonation restores your own. Refused for yourself, inactive or deleted users, CaseWizard staff accounts, users of another firm, and while already logged in as someone else.","tags":["users"]}},"/users/lookup":{"get":{"operationId":"lookupUsers","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserLookupDto"}}}}}},"security":[{"bearer":[]}],"summary":"Active tenant users (id + name) for pickers and filters.","tags":["users"]}},"/notifications":{"get":{"operationId":"listNotifications","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"unreadOnly","required":false,"in":"query","description":"Only return unread notifications.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List notifications visible to the caller.","tags":["notifications"]},"post":{"operationId":"createNotification","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateNotificationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a notification (targeted or tenant-wide).","tags":["notifications"]}},"/notifications/read-all":{"post":{"operationId":"markAllNotificationsRead","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Mark all visible notifications read.","tags":["notifications"]}},"/notifications/{id}/read":{"patch":{"operationId":"markNotificationRead","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationDto"}}}}},"security":[{"bearer":[]}],"summary":"Mark a notification read.","tags":["notifications"]}},"/notifications/{id}":{"delete":{"operationId":"deleteNotification","parameters":[{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a notification.","tags":["notifications"]}},"/account/profile":{"get":{"operationId":"getAccountProfile","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the current tenant's account profile.","tags":["account"]},"patch":{"operationId":"updateAccountProfile","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountProfileDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountProfileDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the current tenant's account profile.","tags":["account"]}},"/account/subscription":{"get":{"operationId":"getAccountSubscription","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionSummaryDto"}}}}},"security":[{"bearer":[]}],"summary":"Subscription summary for the current tenant.","tags":["account"]}},"/account/subscription/billing-contact":{"get":{"operationId":"getAccountBillingContact","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingContactDto"}}}}},"security":[{"bearer":[]}],"summary":"Stripe Customer billing contact for the current tenant (read-only).","tags":["account"]}},"/account/subscription/charges":{"get":{"operationId":"listAccountSubscriptionCharges","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionChargesResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Stripe invoices and credit notes for the current tenant (read-only).","tags":["account"]}},"/account/subscription/plans":{"get":{"operationId":"listAccountSubscriptionPlans","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionPlansResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List purchasable subscription plans.","tags":["account"]}},"/account/subscription/checkout":{"post":{"operationId":"createAccountSubscriptionCheckout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutSessionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutSessionResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Start Stripe Checkout for a subscription (Admin only).","tags":["account"]}},"/account/subscription/portal":{"post":{"operationId":"createAccountSubscriptionPortal","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePortalSessionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalSessionResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"Open the Stripe billing portal (Admin only).","tags":["account"]}},"/host/tenants":{"get":{"operationId":"listHostTenants","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive name contains.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List tenants (host admin).","tags":["host"]},"post":{"operationId":"createHostTenant","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTenantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a tenant (host admin).","tags":["host"]}},"/host/tenants/{id}":{"patch":{"operationId":"updateHostTenant","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTenantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a tenant (host admin).","tags":["host"]},"delete":{"operationId":"deleteHostTenant","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a tenant (host admin).","tags":["host"]}},"/host/tenants/{id}/sync-subscription":{"post":{"operationId":"syncHostTenantSubscription","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantDto"}}}}},"security":[{"bearer":[]}],"summary":"Sync tenant subscription status from Stripe.","tags":["host"]}},"/host/tenants/{id}/users":{"get":{"operationId":"listHostTenantUsers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HostTenantUserDto"}}}}}},"security":[{"bearer":[]}],"summary":"List active users for tenant impersonation.","tags":["host"]}},"/host/tenants/{id}/impersonate":{"post":{"operationId":"impersonateHostTenantUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"user-agent","required":true,"in":"header","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SelectTenantUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthTokensDto"}}}}},"security":[{"bearer":[]}],"summary":"Sign in as an active tenant user.","tags":["host"]}},"/host/tenants/{id}/features":{"get":{"operationId":"getHostTenantFeatures","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFeaturesDto"}}}}},"security":[{"bearer":[]}],"summary":"Read a tenant feature tree.","tags":["host"]},"put":{"operationId":"updateHostTenantFeatures","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTenantFeaturesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFeaturesDto"}}}}},"security":[{"bearer":[]}],"summary":"Save tenant feature overrides.","tags":["host"]}},"/host/tenants/{id}/features/reset":{"post":{"operationId":"resetHostTenantFeatures","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFeaturesDto"}}}}},"security":[{"bearer":[]}],"summary":"Reset tenant feature overrides.","tags":["host"]}},"/host/editions":{"get":{"operationId":"listHostEditions","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EditionDto"}}}}}},"security":[{"bearer":[]}],"summary":"List editions (host admin).","tags":["host"]},"post":{"operationId":"createHostEdition","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEditionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditionDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an edition (host admin).","tags":["host"]}},"/host/editions/{id}":{"patch":{"operationId":"updateHostEdition","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEditionDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditionDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an edition (host admin).","tags":["host"]},"delete":{"operationId":"deleteHostEdition","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete an unused edition (host admin).","tags":["host"]}},"/host/editions/{id}/features":{"get":{"operationId":"getHostEditionFeatures","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFeaturesDto"}}}}},"security":[{"bearer":[]}],"summary":"Get edition features (host admin).","tags":["host"]},"put":{"operationId":"updateHostEditionFeatures","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEditionFeaturesDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFeaturesDto"}}}}},"security":[{"bearer":[]}],"summary":"Update edition features (host admin).","tags":["host"]}},"/host/administration/users":{"get":{"operationId":"HostSystemController_listAdministrationUsers","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive search across the host view.","schema":{"type":"string"}},{"name":"tenantId","required":false,"in":"query","description":"When set, restrict the list to a single tenant (role/user pickers).","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["host"]}},"/host/administration/roles":{"get":{"operationId":"HostSystemController_listAdministrationRoles","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive search across the host view.","schema":{"type":"string"}},{"name":"tenantId","required":false,"in":"query","description":"When set, restrict the list to a single tenant (role/user pickers).","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["host"]}},"/host/administration/languages":{"get":{"operationId":"HostSystemController_listAdministrationLanguages","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive search across the host view.","schema":{"type":"string"}},{"name":"tenantId","required":false,"in":"query","description":"When set, restrict the list to a single tenant (role/user pickers).","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["host"]}},"/host/administration/audit-logs":{"get":{"operationId":"listAdministrationAuditLogs","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive search across the host view.","schema":{"type":"string"}},{"name":"tenantId","required":false,"in":"query","description":"When set, restrict the list to a single tenant (role/user pickers).","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationAuditLogListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List audit logs across tenants (host admin).","tags":["host"]}},"/host/administration/roles/{tenantId}/{id}":{"get":{"operationId":"getHostAdministrationRole","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationRoleDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a tenant role (host admin).","tags":["host"]},"patch":{"operationId":"updateHostAdministrationRole","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoleDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationRoleDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a tenant role and its permissions (host admin).","tags":["host"]},"delete":{"operationId":"deleteHostAdministrationRole","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a tenant role (host admin).","tags":["host"]}},"/host/administration/users/{tenantId}/{id}":{"get":{"operationId":"getHostAdministrationUser","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationUserDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a tenant user (host admin).","tags":["host"]},"patch":{"operationId":"updateHostAdministrationUser","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationUserDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a tenant user and role assignments (host admin).","tags":["host"]}},"/host/administration/languages/{tenantId}/{id}":{"get":{"operationId":"getHostAdministrationLanguage","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationLanguageDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a tenant language (host admin).","tags":["host"]},"patch":{"operationId":"updateHostAdministrationLanguage","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationLanguageDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a tenant language (host admin).","tags":["host"]},"delete":{"operationId":"deleteHostAdministrationLanguage","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a tenant language (host admin).","tags":["host"]}},"/host/administration/languages/{tenantId}/{languageId}/texts":{"get":{"operationId":"listHostAdministrationLanguageTexts","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"languageId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on key or value.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationLanguageTextListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List texts for a tenant language (host admin).","tags":["host"]}},"/host/administration/languages/{tenantId}/{languageId}/texts/{id}":{"get":{"operationId":"getHostAdministrationLanguageText","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"languageId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageTextDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a tenant language text (host admin).","tags":["host"]},"patch":{"operationId":"updateHostAdministrationLanguageText","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"languageId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguageTextDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageTextDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a tenant language text (host admin).","tags":["host"]},"delete":{"operationId":"deleteHostAdministrationLanguageText","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"languageId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a tenant language text (host admin).","tags":["host"]}},"/host/administration/audit-logs/{id}":{"get":{"operationId":"getHostAdministrationAuditLog","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationAuditLogDetailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an audit log detail record (host admin).","tags":["host"]}},"/host/welcome-email":{"get":{"operationId":"getWelcomeEmail","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WelcomeEmailDto"}}}}},"security":[{"bearer":[]}],"summary":"Get the tenant-registration welcome email template.","tags":["host"]},"put":{"operationId":"updateWelcomeEmail","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateWelcomeEmailDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WelcomeEmailDto"}}}}},"security":[{"bearer":[]}],"summary":"Update the tenant-registration welcome email template.","tags":["host"]}},"/host/stripe/plans":{"get":{"operationId":"listHostStripePlans","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/StripePlanDto"}}}}}},"security":[{"bearer":[]}],"summary":"List active Stripe products for the edition/plan picker.","tags":["host"]}},"/host/settings":{"get":{"operationId":"listHostSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HostSettingDto"}}}}}},"security":[{"bearer":[]}],"summary":"List global host settings.","tags":["host"]},"put":{"operationId":"updateHostSettings","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHostSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HostSettingDto"}}}}}},"security":[{"bearer":[]}],"summary":"Upsert global host settings.","tags":["host"]}},"/host/maintenance":{"get":{"operationId":"getMaintenanceStatus","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MaintenanceStatusDto"}}}}},"security":[{"bearer":[]}],"summary":"Runtime + queue health.","tags":["host"]}},"/host/maintenance/contact-orphans":{"get":{"operationId":"getContactOrphanReport","parameters":[{"name":"tenantId","required":false,"in":"query","description":"Limit the report to one tenant.","schema":{"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Maximum rows listed.","schema":{"maximum":1000,"default":200,"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactOrphanReportDto"}}}}},"security":[{"bearer":[]}],"summary":"Read-only report of case links and billing entities that point at people or organizations deleted while still linked. Nothing is restored.","tags":["host"]}},"/host/maintenance/test-job":{"post":{"operationId":"enqueueMaintenanceTestJob","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"jobId":{"type":"string"}}}}}}},"security":[{"bearer":[]}],"summary":"Enqueue a probe job.","tags":["host"]}},"/host/maintenance/clean-queues":{"post":{"operationId":"cleanMaintenanceQueues","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"removed":{"type":"number"}}}}}}},"security":[{"bearer":[]}],"summary":"Clear finished queue jobs.","tags":["host"]}},"/host/feature-requests":{"get":{"operationId":"listHostFeatureRequests","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on title or description.","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string","enum":["requested","under_review","planned","in_progress","shipped","closed"]}},{"name":"sort","required":false,"in":"query","schema":{"type":"string","enum":["top","new","active"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostFeatureRequestListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List every feature request with per-status counts (host admin).","tags":["host"]}},"/host/feature-requests/{id}":{"get":{"operationId":"getHostFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a feature request (host admin).","tags":["host"]},"patch":{"operationId":"updateHostFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateHostFeatureRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Edit a feature request, change its status, close it, or lock comments (host admin). Status changes email followers.","tags":["host"]},"delete":{"operationId":"deleteHostFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete a feature request (soft delete, host admin).","tags":["host"]}},"/host/feature-requests/{id}/followers":{"get":{"operationId":"getHostFeatureRequestFollowers","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestFollowerCountDto"}}}}},"security":[{"bearer":[]}],"summary":"Count the people following a feature request (host admin).","tags":["host"]}},"/host/feature-requests/{id}/comments":{"get":{"operationId":"listHostFeatureRequestComments","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestCommentListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List the discussion on a feature request (host admin).","tags":["host"]},"post":{"operationId":"createHostFeatureRequestComment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeatureRequestCommentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestCommentDto"}}}}},"security":[{"bearer":[]}],"summary":"Reply as CaseWizard staff, even on locked or closed requests (host admin).","tags":["host"]}},"/host/feature-requests/comments/{commentId}":{"delete":{"operationId":"deleteHostFeatureRequestComment","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Remove any user's comment or a status event from the thread (host admin).","tags":["host"]}},"/community/feature-requests":{"get":{"operationId":"listFeatureRequests","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on title or description.","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","description":"Filter by status. Closed requests are hidden unless requested explicitly.","schema":{"type":"string","enum":["requested","under_review","planned","in_progress","shipped","closed"]}},{"name":"sort","required":false,"in":"query","description":"top = highest net score (default), new = newest first, active = latest activity.","schema":{"type":"string","enum":["top","new","active"]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List community feature requests (paginated, filterable, sortable).","tags":["community"]},"post":{"operationId":"createFeatureRequest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeatureRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Submit a feature request (enters the roadmap as Community Requested).","tags":["community"]}},"/community/feature-requests/{id}":{"get":{"operationId":"getFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Get one feature request with your vote and follow state.","tags":["community"]}},"/community/feature-requests/{id}/vote":{"post":{"operationId":"voteFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteFeatureRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestDto"}}}}},"security":[{"bearer":[]}],"summary":"Set your vote on a feature request (1 up, -1 down, 0 clear).","tags":["community"]}},"/community/feature-requests/{id}/comments":{"get":{"operationId":"listFeatureRequestComments","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestCommentListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List the discussion on a feature request (top-level comments with replies).","tags":["community"]},"post":{"operationId":"createFeatureRequestComment","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFeatureRequestCommentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestCommentDto"}}}}},"security":[{"bearer":[]}],"summary":"Comment on a feature request, or reply to a comment. Follows the request.","tags":["community"]}},"/community/comments/{commentId}":{"patch":{"operationId":"updateFeatureRequestComment","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFeatureRequestCommentDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeatureRequestCommentDto"}}}}},"security":[{"bearer":[]}],"summary":"Edit your own comment.","tags":["community"]},"delete":{"operationId":"deleteFeatureRequestComment","parameters":[{"name":"commentId","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Delete your own comment (replies stay in the thread).","tags":["community"]}},"/community/feature-requests/{id}/follow":{"put":{"operationId":"followFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowStateDto"}}}}},"security":[{"bearer":[]}],"summary":"Follow a feature request: get emailed on status changes and new comments.","tags":["community"]},"delete":{"operationId":"unfollowFeatureRequest","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowStateDto"}}}}},"security":[{"bearer":[]}],"summary":"Stop following a feature request.","tags":["community"]}},"/community/unsubscribe":{"post":{"operationId":"unsubscribeFromCommunityEmails","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeResultDto"}}}}},"security":[{"bearer":[]}],"summary":"One-click unsubscribe from an email link: stop following one request, or all community email.","tags":["community"]}},"/languages":{"get":{"operationId":"listLanguages","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on name or display name.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List languages.","tags":["languages"]},"post":{"operationId":"createLanguage","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLanguageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a language.","tags":["languages"]}},"/languages/{id}":{"get":{"operationId":"getLanguage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a language by id.","tags":["languages"]},"patch":{"operationId":"updateLanguage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguageDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a language.","tags":["languages"]},"delete":{"operationId":"deleteLanguage","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a language.","tags":["languages"]}},"/languages/{id}/texts":{"get":{"operationId":"listLanguageTexts","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on key or value.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageTextListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List a language's texts.","tags":["languages"]},"post":{"operationId":"createLanguageText","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLanguageTextDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageTextDto"}}}}},"security":[{"bearer":[]}],"summary":"Add a text to a language.","tags":["languages"]}},"/language-texts/{id}":{"patch":{"operationId":"updateLanguageText","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLanguageTextDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageTextDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a language text.","tags":["languages"]},"delete":{"operationId":"deleteLanguageText","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a language text.","tags":["languages"]}},"/organization-units":{"get":{"operationId":"listOrganizationUnits","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on display name or code.","schema":{"type":"string"}},{"name":"parentId","required":false,"in":"query","description":"Filter to children of this parent.","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUnitListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List organization units.","tags":["organization-units"]},"post":{"operationId":"createOrganizationUnit","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationUnitDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUnitDto"}}}}},"security":[{"bearer":[]}],"summary":"Create an organization unit.","tags":["organization-units"]}},"/organization-units/{id}":{"get":{"operationId":"getOrganizationUnit","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUnitDto"}}}}},"security":[{"bearer":[]}],"summary":"Get an organization unit by id.","tags":["organization-units"]},"patch":{"operationId":"updateOrganizationUnit","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationUnitDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUnitDto"}}}}},"security":[{"bearer":[]}],"summary":"Update an organization unit.","tags":["organization-units"]},"delete":{"operationId":"deleteOrganizationUnit","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete an organization unit.","tags":["organization-units"]}},"/billing-codes":{"get":{"operationId":"listBillingCodesAdmin","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Substring match on code or description.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCodeListResponseDto"}}}}},"security":[{"bearer":[]}],"summary":"List billing codes (paginated).","tags":["billing-codes"]},"post":{"operationId":"createBillingCode","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBillingCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCodeDto"}}}}},"security":[{"bearer":[]}],"summary":"Create a billing code.","tags":["billing-codes"]}},"/billing-codes/{id}":{"get":{"operationId":"getBillingCode","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCodeDto"}}}}},"security":[{"bearer":[]}],"summary":"Get a billing code by id.","tags":["billing-codes"]},"patch":{"operationId":"updateBillingCode","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillingCodeDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingCodeDto"}}}}},"security":[{"bearer":[]}],"summary":"Update a billing code.","tags":["billing-codes"]},"delete":{"operationId":"deleteBillingCode","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Soft-delete a billing code.","tags":["billing-codes"]}},"/product-releases":{"get":{"operationId":"listProductReleases","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductReleaseFeedDto"}}}}},"summary":"List customer-facing CaseWizard product releases.","tags":["product releases"]}},"/migration/ingest":{"post":{"operationId":"migrationIngest","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestRequestDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Bulk natural-key upsert of pre-transformed records.","tags":["migration"]}},"/migration/runs":{"post":{"operationId":"migrationStartRun","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartRunDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"runId":{"type":"string"}}}}}}},"security":[{"migration-token":[]}],"summary":"Start a migration run.","tags":["migration"]}},"/migration/runs/{runId}/finish":{"post":{"operationId":"migrationFinishRun","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"properties":{"runId":{"type":"string"}}}}}}},"security":[{"migration-token":[]}],"summary":"Mark a run finished.","tags":["migration"]}},"/migration/runs/latest":{"get":{"operationId":"migrationLatestRun","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LatestRunDto"}}}}},"security":[{"migration-token":[]}],"summary":"Latest real (mode=run) run id.","tags":["migration"]}},"/migration/runs/{runId}/entity-stats":{"get":{"operationId":"migrationReadEntityStats","parameters":[{"name":"runId","required":true,"in":"path","schema":{"type":"string"}},{"name":"tenantIds","required":false,"in":"query","description":"Comma-separated tenant ids; omit for all.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityStatsReadResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Per-entity tallies for a run (verify reconcile).","tags":["migration"]}},"/migration/entity-stats":{"post":{"operationId":"migrationRecordEntityStats","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EntityStatsBatchDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkCountDto"}}}}},"security":[{"migration-token":[]}],"summary":"Record per-entity tallies for a run.","tags":["migration"]}},"/migration/crosswalk":{"post":{"operationId":"migrationRecordCrosswalk","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosswalkBatchDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkCountDto"}}}}},"security":[{"migration-token":[]}],"summary":"Batch upsert migration_id_map rows.","tags":["migration"]},"get":{"operationId":"migrationReadCrosswalk","parameters":[{"name":"tenantIds","required":false,"in":"query","description":"Comma-separated tenant ids; host-global rows are always included. Omit for all.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CrosswalkResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"All migration_id_map rows (resume hydrate).","tags":["migration"]}},"/migration/quarantine":{"post":{"operationId":"migrationRecordQuarantine","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuarantineBatchDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkCountDto"}}}}},"security":[{"migration-token":[]}],"summary":"Batch insert migration_quarantine rows.","tags":["migration"]}},"/migration/lookups":{"get":{"operationId":"migrationLookups","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupsResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Seeded reference lookups (client preload).","tags":["migration"]}},"/migration/count":{"get":{"operationId":"migrationCount","parameters":[{"name":"model","required":true,"in":"query","schema":{"type":"string"}},{"name":"tenantIds","required":false,"in":"query","description":"Comma-separated tenant ids; omit for all.","schema":{"type":"string"}},{"name":"where","required":false,"in":"query","description":"JSON Prisma where-filter (discriminator).","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CountResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Target row count for a model.","tags":["migration"]}},"/migration/sum":{"get":{"operationId":"migrationSum","parameters":[{"name":"model","required":true,"in":"query","schema":{"type":"string"}},{"name":"column","required":true,"in":"query","description":"Prisma (camelCase) field name.","schema":{"type":"string"}},{"name":"tenantIds","required":false,"in":"query","description":"Comma-separated tenant ids; omit for all.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SumResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"SUM of a money column for a model.","tags":["migration"]}},"/migration/grants":{"get":{"operationId":"migrationGrants","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GrantsResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"App-role grant verdicts (R4).","tags":["migration"]}},"/migration/grants/repair":{"post":{"operationId":"migrationRepairGrants","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepairGrantsResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Idempotent app-role grant repair (R4).","tags":["migration"]}},"/migration/prepare":{"post":{"operationId":"migrationPrepare","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrepareDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrepareResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Prisma migrate deploy + baseline seed + grant repair (api-mode prepare-target).","tags":["migration"]}},"/migration/identities/backfill":{"post":{"operationId":"migrationBackfillIdentities","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdentityBackfillResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Idempotent identity backfill: derive identities from users and link memberships.","tags":["migration"]}},"/migration/billing-settings/backfill":{"post":{"operationId":"migrationBackfillBillingSettings","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSettingsBackfillResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Recover BillingSetting.nextInvoiceNumber from MAX(invoice_number)+1 (no legacy BillingSetting table).","tags":["migration"]}},"/migration/tenants/firm-details":{"post":{"operationId":"migrationCarryTenantFirmDetails","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFirmDetailsBatchDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantFirmDetailsResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Fill blank tenant FEIN, legal name and address from legacy CustomerProfile and its Company organization (never overwrites).","tags":["migration"]}},"/migration/sync-sequences":{"post":{"operationId":"migrationSyncSequences","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncSequencesResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Advance every public serial/identity sequence to at least MAX(column) after explicit-id import.","tags":["migration"]}},"/migration/cascade-deleted-cases":{"post":{"operationId":"migrationCascadeDeletedCases","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CascadeDeletedCasesResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Soft-delete the case-owned records (events, participants, documents, ...) of every deleted case; billing and audit rows are kept.","tags":["migration"]}},"/migration/rerate-fixed-fee-time":{"post":{"operationId":"migrationRerateFixedFeeTime","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RerateFixedFeeTimeResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Re-rate not-yet-invoiced time on Fixed Fee cases to $0 (legacy rated it hours x firm rate; the fee is billed as its own invoice line).","tags":["migration"]}},"/migration/clear-tenant":{"post":{"operationId":"migrationClearTenant","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClearTenantDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClearTenantResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Reverse-dependency tenant wipe (host-global preserved).","tags":["migration"]}},"/migration/rollback":{"post":{"operationId":"migrationRollback","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollbackDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RollbackResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Delete every row tagged with a run id.","tags":["migration"]}},"/migration/reset-password":{"post":{"operationId":"migrationResetPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationResetPasswordDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Overwrite password_hash (argon2) for scoped users.","tags":["migration"]}},"/migration/lookup-users":{"get":{"operationId":"migrationLookupUsers","parameters":[{"name":"identifier","required":true,"in":"query","description":"Email (case-insensitive) or exact userName.","schema":{"type":"string"}},{"name":"tenantIds","required":false,"in":"query","description":"Comma-separated tenant ids; omit for all.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LookupUsersResponseDto"}}}}},"security":[{"migration-token":[]}],"summary":"Find users by email/userName (login facts).","tags":["migration"]}},"/platform/tenants":{"get":{"operationId":"platformListTenants","parameters":[{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive name contains.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantListResponseDto"}}}}},"security":[{"platform-token":[]}],"summary":"List tenants (platform token).","tags":["platform"]}},"/platform/tenants/{tenantId}/users":{"get":{"operationId":"platformListTenantUsers","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","schema":{"minimum":1,"default":1,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"pageSize","required":false,"in":"query","schema":{"minimum":1,"maximum":100,"default":20,"allOf":[{"$ref":"#/components/schemas/Object"}]}},{"name":"search","required":false,"in":"query","description":"Case-insensitive search across the tenant user list.","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationUserListResponseDto"}}}}},"security":[{"platform-token":[]}],"summary":"List a tenant's users (platform token).","tags":["platform"]}},"/platform/tenants/{tenantId}/users/{id}":{"patch":{"operationId":"platformSetUserActive","parameters":[{"name":"tenantId","required":true,"in":"path","schema":{"type":"number"}},{"name":"id","required":true,"in":"path","schema":{"format":"int64","type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformSetUserActiveDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostAdministrationUserDetailDto"}}}}},"security":[{"platform-token":[]}],"summary":"Enable or disable a tenant user (platform token).","tags":["platform"]}}},"info":{"title":"CaseWizard API","description":"Legal practice management REST API.\n\n**MCP server:** Connect Cursor or Claude Desktop to the hosted CaseWizard MCP server. See the [MCP server guide](/docs/mcp) for setup, tools, and examples.","version":"062b1614259ab4d810e4deb7e4fba23bf5116c42","contact":{}},"tags":[],"servers":[{"url":"/v1"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"},"api-key":{"type":"apiKey","in":"header","name":"X-Api-Key"},"migration-token":{"type":"apiKey","in":"header","name":"X-Migration-Token"},"platform-token":{"type":"apiKey","in":"header","name":"X-Platform-Token"},"oauth2":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"/v1/auth/token","scopes":{"cases:read":"Access to cases read","cases:write":"Access to cases write","people:read":"Access to people read","people:write":"Access to people write","documents:read":"Access to documents read","documents:write":"Access to documents write","calendar:read":"Access to calendar read","calendar:write":"Access to calendar write","medical:read":"Access to medical read","medical:write":"Access to medical write","criminal:read":"Access to criminal read","criminal:write":"Access to criminal write","billing:read":"Access to billing read","billing:write":"Access to billing write","reports:read":"Access to reports read","reports:write":"Access to reports write","lookups:read":"Access to lookups read","lookups:write":"Access to lookups write","webhooks:read":"Access to webhooks read","webhooks:write":"Access to webhooks write"}}}}},"schemas":{"LoginDto":{"type":"object","properties":{"email":{"type":"string","example":"jdoe@example.com","description":"Your email address (the login identifier)."},"password":{"type":"string","format":"password","description":"Your account password."}},"required":["email","password"]},"AuthTokensDto":{"type":"object","properties":{"accessToken":{"type":"string"},"refreshToken":{"type":"string"},"expiresIn":{"type":"number","description":"Access-token lifetime in seconds."}},"required":["accessToken","refreshToken","expiresIn"]},"TenantChoiceDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"LoginResponseDto":{"type":"object","properties":{"status":{"type":"string","enum":["authenticated","mfa_required","select_tenant"]},"tokens":{"$ref":"#/components/schemas/AuthTokensDto"},"challengeToken":{"type":"string","description":"Opaque token for the /auth/mfa/verify step."},"selectionToken":{"type":"string","description":"Opaque token for the /auth/select-tenant step."},"tenants":{"type":"array","items":{"$ref":"#/components/schemas/TenantChoiceDto"}},"staffPortal":{"type":"boolean","description":"Whether the selection screen should offer the CaseWizard Staff Management portal."}},"required":["status"]},"SelectTenantDto":{"type":"object","properties":{"selectionToken":{"type":"string","description":"The selection token returned by login/mfa-verify."},"tenantId":{"type":"number","description":"The chosen tenant id."}},"required":["selectionToken","tenantId"]},"SelectStaffPortalDto":{"type":"object","properties":{"selectionToken":{"type":"string","description":"The selection token returned by login or MFA verification."}},"required":["selectionToken"]},"DeviceStartDto":{"type":"object","properties":{"clientName":{"type":"string","maxLength":80,"default":"CaseWizard for Word","description":"Name of the app asking to sign in, shown on the approval page."}}},"DeviceStartResponseDto":{"type":"object","properties":{"deviceCode":{"type":"string","description":"Secret polled by the requesting app (43-char base64url). Never shown to people."},"userCode":{"type":"string","example":"BCDF-GHJK","description":"Short code the person confirms on the approval page."},"verificationUri":{"type":"string","example":"https://app.casewizard.com/device"},"verificationUriComplete":{"type":"string","example":"https://app.casewizard.com/device?code=BCDF-GHJK"},"expiresIn":{"type":"number","description":"Seconds until the codes expire.","example":600},"interval":{"type":"number","description":"Minimum seconds between token polls.","example":3}},"required":["deviceCode","userCode","verificationUri","verificationUriComplete","expiresIn","interval"]},"DeviceLookupResponseDto":{"type":"object","properties":{"clientName":{"type":"string"},"requestedAt":{"type":"string","format":"date-time"},"ipAddress":{"type":"string","description":"IP address that started the request."},"userAgent":{"type":"string","description":"Browser or app that started the request."},"status":{"type":"string","enum":["pending"]}},"required":["clientName","requestedAt","status"]},"DeviceApproveDto":{"type":"object","properties":{"userCode":{"type":"string","example":"BCDF-GHJK","description":"The code shown in the requesting app (case, hyphen and spaces ignored)."},"approve":{"type":"boolean","description":"true to sign the requesting app in, false to deny it."}},"required":["userCode","approve"]},"DeviceTokenDto":{"type":"object","properties":{"deviceCode":{"type":"string","description":"The deviceCode returned by /auth/device/start."}},"required":["deviceCode"]},"MyTenantsResponseDto":{"type":"object","properties":{"tenants":{"type":"array","items":{"$ref":"#/components/schemas/TenantChoiceDto"}},"staffPortal":{"type":"boolean","description":"Whether the picker should offer CaseWizard Staff Management."}},"required":["tenants","staffPortal"]},"SwitchTenantDto":{"type":"object","properties":{"tenantId":{"type":"number","description":"The tenant id to switch into."},"refreshToken":{"type":"string","description":"Current refresh token to revoke after the switch (recommended)."}},"required":["tenantId"]},"SessionTransitionDto":{"type":"object","properties":{"refreshToken":{"type":"string","description":"Current refresh token to revoke after the transition (recommended)."}}},"MfaVerifyDto":{"type":"object","properties":{"challengeToken":{"type":"string","description":"The challenge token returned by login."},"code":{"type":"string","example":"123456","description":"A TOTP code or a backup code."}},"required":["challengeToken","code"]},"MfaEnrollDto":{"type":"object","properties":{"currentCode":{"type":"string","example":"123456","description":"Required only when MFA is already enabled: a current TOTP or backup code, to prove possession before overwriting the factor."}}},"MfaEnrollmentDto":{"type":"object","properties":{"secret":{"type":"string","description":"The TOTP shared secret (base32), for manual entry."},"otpauthUrl":{"type":"string","description":"otpauth:// URI to add to an authenticator app."},"qrDataUrl":{"type":"string","description":"The otpauth URI rendered as a PNG data URL."}},"required":["secret","otpauthUrl","qrDataUrl"]},"MfaActivateDto":{"type":"object","properties":{"code":{"type":"string","example":"123456","description":"A TOTP code from your authenticator app."},"label":{"type":"string","example":"Work phone","maxLength":100,"description":"A friendly name for this authenticator (e.g. \"Work phone\")."}},"required":["code"]},"MfaBackupCodesDto":{"type":"object","properties":{"backupCodes":{"description":"One-time backup codes; shown only once.","type":"array","items":{"type":"string"}}},"required":["backupCodes"]},"MfaCodeDto":{"type":"object","properties":{"code":{"type":"string","example":"123456","description":"A TOTP code from your authenticator app."}},"required":["code"]},"MagicLinkRequestDto":{"type":"object","properties":{"email":{"type":"string","example":"jdoe@example.com"}},"required":["email"]},"MagicLinkConsumeDto":{"type":"object","properties":{"token":{"type":"string","description":"The single-use token from the sign-in link."}},"required":["token"]},"PasskeyRegistrationVerifyDto":{"type":"object","properties":{"response":{"type":"object","additionalProperties":true,"description":"The WebAuthn registration response from the browser."},"label":{"type":"string","example":"MacBook Touch ID","maxLength":100,"description":"A friendly name for this passkey (e.g. \"MacBook Touch ID\")."}},"required":["response"]},"PasskeyLoginOptionsDto":{"type":"object","properties":{"email":{"type":"string","example":"jdoe@example.com"}},"required":["email"]},"PasskeyLoginVerifyDto":{"type":"object","properties":{"email":{"type":"string","example":"jdoe@example.com"},"response":{"type":"object","additionalProperties":true,"description":"The WebAuthn assertion response from the browser."}},"required":["email","response"]},"PasskeyDiscoverVerifyDto":{"type":"object","properties":{"response":{"type":"object","additionalProperties":true,"description":"The WebAuthn assertion response from the browser."}},"required":["response"]},"PasskeyDto":{"type":"object","properties":{"id":{"type":"string","description":"Passkey id."},"label":{"type":"string","nullable":true,"description":"User-assigned label, if any."},"transports":{"description":"Authenticator transports reported at registration.","type":"array","items":{"type":"string"}},"lastUsedAt":{"type":"string","nullable":true,"description":"Last successful sign-in with this passkey."},"createdAt":{"format":"date-time","type":"string","description":"When this passkey was registered."}},"required":["id","label","transports","lastUsedAt","createdAt"]},"PasskeyListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PasskeyDto"}}},"required":["items"]},"PasskeyRevokeDto":{"type":"object","properties":{"code":{"type":"string","example":"123456","description":"A current TOTP or backup code. Required when two-step verification is enabled."}}},"RegisterDto":{"type":"object","properties":{"tenant":{"type":"string","example":"your-tenant","description":"Tenant name or numeric id to join."},"userName":{"type":"string","example":"jdoe","description":"Optional display username; defaults to the email."},"email":{"type":"string","example":"jdoe@example.com"},"password":{"type":"string","format":"password","minLength":8,"description":"At least 8 characters with an uppercase letter, a lowercase letter, a number, and a special character."},"firstName":{"type":"string"},"lastName":{"type":"string"}},"required":["tenant","email","password"]},"SignupDto":{"type":"object","properties":{"companyName":{"type":"string","example":"Acme Law","description":"Your firm or company name."},"firstName":{"type":"string","example":"Jane"},"lastName":{"type":"string","example":"Doe"},"email":{"type":"string","example":"jdoe@example.com"},"password":{"type":"string","format":"password","minLength":6},"turnstileToken":{"type":"string","description":"Cloudflare Turnstile response token."}},"required":["companyName","firstName","lastName","email","password","turnstileToken"]},"ForgotPasswordDto":{"type":"object","properties":{"email":{"type":"string","example":"jdoe@example.com","description":"The account email (credentials are global to the identity)."}},"required":["email"]},"ConfirmEmailDto":{"type":"object","properties":{"token":{"type":"string","description":"The single-use email confirmation token."}},"required":["token"]},"ActivateAccountDto":{"type":"object","properties":{"token":{"type":"string","description":"The single-use token from the activation email link."},"newPassword":{"type":"string","example":"NewPassw0rd!","description":"Required when the link was sent with mode=set-password; ignored otherwise. At least 8 characters with an uppercase letter, a lowercase letter, a number, and a special character."}},"required":["token"]},"ResetPasswordDto":{"type":"object","properties":{"token":{"type":"string","description":"The single-use reset token from the reset link."},"newPassword":{"type":"string","example":"NewPassw0rd!","description":"At least 8 characters with an uppercase letter, a lowercase letter, a number, and a special character."}},"required":["token","newPassword"]},"ChangePasswordDto":{"type":"object","properties":{"currentPassword":{"type":"string","format":"password","description":"Your current password (re-authenticates the change)."},"newPassword":{"type":"string","format":"password","minLength":8,"example":"NewPassw0rd!","description":"At least 8 characters with an uppercase letter, a lowercase letter, a number, and a special character."}},"required":["currentPassword","newPassword"]},"RefreshDto":{"type":"object","properties":{"refreshToken":{"type":"string"}},"required":["refreshToken"]},"LogoutDto":{"type":"object","properties":{"refreshToken":{"type":"string"}},"required":["refreshToken"]},"OAuthTokenRequestDto":{"type":"object","properties":{"grantType":{"type":"string","enum":["client_credentials"],"example":"client_credentials"},"clientId":{"type":"string","description":"OAuth client id."},"clientSecret":{"type":"string","description":"OAuth client secret."},"scope":{"type":"string","description":"Space-delimited subset of granted scopes."}},"required":["grantType","clientId","clientSecret"]},"OAuthTokenResponseDto":{"type":"object","properties":{"accessToken":{"type":"string"},"tokenType":{"type":"string","enum":["Bearer"],"example":"Bearer"},"expiresIn":{"type":"number","description":"Access-token lifetime in seconds."},"scope":{"type":"string","description":"Space-delimited granted scopes."}},"required":["accessToken","tokenType","expiresIn","scope"]},"CurrentUserDto":{"type":"object","properties":{"userId":{"type":"string"},"tenantId":{"type":"number"},"userName":{"type":"string"},"email":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"isHost":{"type":"boolean","description":"Platform super-admin: may use the /host admin screens."},"isImpersonating":{"type":"boolean","description":"True while signed in as another user (host staff impersonation or tenant Login-as)."},"availableTenantCount":{"type":"number","description":"Number of active tenant memberships for this identity (workspace switcher)."},"mfaEnabled":{"type":"boolean","description":"Whether TOTP two-step verification is enabled on the account."},"mfaLabel":{"type":"string","nullable":true,"description":"User-assigned label for the authenticator app, when MFA is enabled."},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true},"trialEndsAt":{"type":"string","nullable":true},"trialDaysRemaining":{"type":"number","nullable":true},"subscriptionStatus":{"type":"string"},"requiresSubscription":{"type":"boolean"},"canAccessApp":{"type":"boolean"},"newUiAvailable":{"type":"boolean","description":"Whether this user may use the new web UI (platform staff, or their tenant has early access)."},"uiPreference":{"type":"string","enum":["classic","new"],"description":"The web UI the user chose. Always 'classic' while newUiAvailable is false, whatever was stored."}},"required":["userId","tenantId","userName","email","permissions","isHost","isImpersonating","availableTenantCount","mfaEnabled","mfaLabel","firstName","lastName","phoneNumber","trialEndsAt","trialDaysRemaining","subscriptionStatus","requiresSubscription","canAccessApp","newUiAvailable","uiPreference"]},"UpdateCurrentUserDto":{"type":"object","properties":{"userName":{"type":"string","description":"Display username; unique within the tenant."},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"phoneNumber":{"type":"string","nullable":true}}},"UpdateUiPreferenceDto":{"type":"object","properties":{"uiPreference":{"type":"string","enum":["classic","new"]}},"required":["uiPreference"]},"LoginAttemptDto":{"type":"object","properties":{"id":{"type":"string"},"success":{"type":"boolean","description":"Whether the credentials were accepted."},"method":{"type":"string","description":"How the sign-in was attempted: 'password' | 'passkey' | 'magic_link' | 'device'."},"failureReason":{"type":"string","nullable":true,"description":"Why the attempt failed, when unsuccessful."},"ipAddress":{"type":"string","nullable":true,"description":"Client IP address, if known."},"userAgent":{"type":"string","nullable":true,"description":"Client user-agent string, if known."},"createdAt":{"format":"date-time","type":"string","description":"When the attempt occurred."}},"required":["id","success","method","failureReason","ipAddress","userAgent","createdAt"]},"LoginAttemptListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LoginAttemptDto"}}},"required":["items"]},"AvatarDto":{"type":"object","properties":{"dataUrl":{"type":"string","nullable":true,"description":"The profile picture as a data URL (bytes loaded from object storage), or null if none is set."}},"required":["dataUrl"]},"EmailDocumentDto":{"type":"object","properties":{"to":{"type":"string","description":"Recipient. Defaults to the billing-entity contact email."},"cc":{"type":"string","description":"CC recipient."},"subject":{"type":"string"},"body":{"type":"string"}}},"EmailResultDto":{"type":"object","properties":{"sent":{"type":"boolean","description":"True when an SMTP send occurred; false in log-only mode."},"transport":{"type":"string","enum":["smtp","log"],"description":"Transport that handled the message."}},"required":["sent","transport"]},"EmailInvoiceBatchDto":{"type":"object","properties":{"invoiceIds":{"description":"Invoices to email to their billing-entity contact.","type":"array","items":{"type":"number"}},"subject":{"type":"string"},"body":{"type":"string"}},"required":["invoiceIds"]},"EmailInvoiceBatchResultItemDto":{"type":"object","properties":{"invoiceId":{"type":"number"},"ok":{"type":"boolean"},"transport":{"type":"object","nullable":true,"description":"Transport when ok=true."},"error":{"type":"object","nullable":true,"description":"Reason when ok=false."}},"required":["invoiceId","ok","transport","error"]},"EmailInvoiceBatchResultDto":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/EmailInvoiceBatchResultItemDto"}}},"required":["results"]},"EmailCaseStatementDto":{"type":"object","properties":{"to":{"type":"string","description":"Recipient. Defaults to the billing-entity contact email."},"cc":{"type":"string","description":"CC recipient."},"subject":{"type":"string"},"body":{"type":"string"},"asOf":{"type":"string","description":"As-of date for the statement and its aging (defaults to now), as for the statement PDF.","example":"2026-06-30"}}},"ReportParamsDto":{"type":"object","properties":{"caseId":{"type":"number"},"eventId":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"preBillId":{"type":"number"},"startDate":{"type":"string"},"endDate":{"type":"string"}}},"ReportEnqueuedDto":{"type":"object","properties":{"reportKey":{"type":"string"},"jobId":{"type":"string","description":"Background job id; poll /v1/reports/jobs/{jobId} for the PDF."}},"required":["reportKey","jobId"]},"JobResultDto":{"type":"object","properties":{"fileName":{"type":"string"},"contentType":{"type":"string"},"storageRef":{"type":"object","description":"Storage linkage for the produced binary."},"sharepointWebUrl":{"type":"object","nullable":true,"description":"Browser URL of the produced file in SharePoint, when the job uploaded it there. Clients should prefer this over base64: a handler that uploads sets this and omits base64."},"webUrl":{"type":"object","nullable":true,"description":"Browser URL of the produced file in the active document store. Alias for sharepointWebUrl when the provider is Egnyte."},"base64":{"type":"string","description":"Inline artifact (base64), for small outputs."},"meta":{"type":"object"}},"required":["fileName","contentType"]},"JobStatusDto":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","description":"Job type (report, export, document-merge, ...)."},"state":{"type":"string","enum":["waiting","active","completed","failed","delayed","unknown"]},"progress":{"type":"number","description":"0-100."},"result":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/JobResultDto"}]},"failedReason":{"type":"object","nullable":true}},"required":["id","type","state","progress","result","failedReason"]},"Object":{"type":"object","properties":{}},"InvoiceDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"invoiceNumber":{"type":"number","description":"Numeric invoice number (LEDES INVOICE_NUMBER, sorting)."},"numberPrefix":{"type":"string","nullable":true,"description":"Prefix captured when the invoice was issued."},"displayNumber":{"type":"string","description":"Number shown to people: numberPrefix + invoiceNumber."},"invoiceDate":{"format":"date-time","type":"string"},"startDate":{"format":"date-time","type":"string"},"endDate":{"format":"date-time","type":"string"},"dueDate":{"type":"object","nullable":true},"datePaid":{"type":"object","nullable":true},"invoiceTermsId":{"type":"object","nullable":true},"invoiceStageId":{"type":"object","nullable":true},"invoiceStageName":{"type":"object","nullable":true,"description":"Joined InvoiceStage.name."},"description":{"type":"object","nullable":true},"isFixedFee":{"type":"boolean"},"isManualInvoice":{"type":"boolean"},"isFinal":{"type":"boolean"},"creationTime":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Joined Case.caseStyle."},"billingEntityName":{"type":"object","nullable":true,"description":"Joined Case.billingEntity.name."},"balance":{"type":"string","description":"totalInvoice - totalPaid - writeOffs for this invoice."},"totalInvoice":{"type":"string","description":"totalFees + totalExpenses (rounded to cents)."}},"required":["id","caseId","invoiceNumber","numberPrefix","displayNumber","invoiceDate","startDate","endDate","dueDate","datePaid","invoiceTermsId","invoiceStageId","invoiceStageName","description","isFixedFee","isManualInvoice","isFinal","creationTime","caseStyle","billingEntityName","balance","totalInvoice"]},"PageMetaDto":{"type":"object","properties":{"total":{"type":"number"},"page":{"type":"number"},"pageSize":{"type":"number"},"pageCount":{"type":"number"}},"required":["total","page","pageSize","pageCount"]},"InvoiceListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"InvoiceTermsDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"value":{"type":"number"}},"required":["id","name","value"]},"NamedLookupDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"NewInvoiceDefaultsDto":{"type":"object","properties":{"caseId":{"type":"number","nullable":true},"invoiceNumber":{"type":"number","description":"Next number from the counter (not reserved until the invoice is saved)."},"numberPrefix":{"type":"string","nullable":true,"description":"Current tenant invoice prefix."},"displayNumber":{"type":"string","description":"numberPrefix + invoiceNumber."},"invoiceDate":{"format":"date-time","type":"string"},"startDate":{"format":"date-time","type":"string"},"endDate":{"format":"date-time","type":"string"},"invoiceTermsId":{"type":"number","nullable":true},"dueDate":{"format":"date-time","type":"string","nullable":true},"invoiceStageId":{"type":"number"},"isManualInvoice":{"type":"boolean"},"fixedFeeAvailable":{"type":"string","nullable":true,"description":"The case's fixed fee still left to bill (decimal string). Null when no case is given or its billing entity is not Fixed Fee."},"terms":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceTermsDto"}},"stages":{"type":"array","items":{"$ref":"#/components/schemas/NamedLookupDto"}}},"required":["caseId","invoiceNumber","numberPrefix","displayNumber","invoiceDate","startDate","endDate","invoiceTermsId","dueDate","invoiceStageId","isManualInvoice","fixedFeeAvailable","terms","stages"]},"FixedFeePositionDto":{"type":"object","properties":{"caseId":{"type":"number"},"fee":{"type":"string","description":"The billing entity's fixed fee (decimal string)."},"billed":{"type":"string","description":"Fixed fee already on the case's invoices."},"available":{"type":"string","description":"Fixed fee still left to bill on the case."}},"required":["caseId","fee","billed","available"]},"CreateFixedFeeInvoiceDto":{"type":"object","properties":{"caseId":{"type":"number","description":"Case to bill. Its billing entity must be Fixed Fee."},"invoiceDate":{"type":"string","description":"Invoice date (ISO); the fixed fee line carries the same date."},"amount":{"type":"string","description":"Amount of the fixed fee to bill (decimal string, above 0). Defaults to all of the fee still left to bill.","example":"5000.00"}},"required":["caseId","invoiceDate"]},"InvoicePaymentDto":{"type":"object","properties":{"id":{"type":"number"},"paymentDate":{"format":"date-time","type":"string"},"paymentAmount":{"type":"string"},"checkNumber":{"type":"object","nullable":true},"feesPaid":{"type":"object","nullable":true},"expensesPaid":{"type":"object","nullable":true},"feesWriteOff":{"type":"object","nullable":true},"expensesWriteOff":{"type":"object","nullable":true}},"required":["id","paymentDate","paymentAmount","checkNumber","feesPaid","expensesPaid","feesWriteOff","expensesWriteOff"]},"InvoiceFixedFeeDto":{"type":"object","properties":{"caseFixedFee":{"type":"string","nullable":true,"description":"The billing entity's fixed fee. Null when the entity is no longer Fixed Fee."},"thisInvoice":{"type":"string","description":"Fixed fee billed on this invoice."},"otherInvoices":{"type":"string","description":"Fixed fee billed on the case's other invoices."},"remaining":{"type":"string","description":"Fixed fee still left to bill on the case after this invoice."},"maxThisInvoice":{"type":"string","description":"The most this invoice may carry: caseFixedFee - otherInvoices."}},"required":["caseFixedFee","thisInvoice","otherInvoices","remaining","maxThisInvoice"]},"InvoiceDetailDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"invoiceNumber":{"type":"number","description":"Numeric invoice number (LEDES INVOICE_NUMBER, sorting)."},"numberPrefix":{"type":"string","nullable":true,"description":"Prefix captured when the invoice was issued."},"displayNumber":{"type":"string","description":"Number shown to people: numberPrefix + invoiceNumber."},"invoiceDate":{"format":"date-time","type":"string"},"startDate":{"format":"date-time","type":"string"},"endDate":{"format":"date-time","type":"string"},"dueDate":{"type":"object","nullable":true},"datePaid":{"type":"object","nullable":true},"invoiceTermsId":{"type":"object","nullable":true},"invoiceStageId":{"type":"object","nullable":true},"invoiceStageName":{"type":"object","nullable":true,"description":"Joined InvoiceStage.name."},"description":{"type":"object","nullable":true},"isFixedFee":{"type":"boolean"},"isManualInvoice":{"type":"boolean"},"isFinal":{"type":"boolean"},"creationTime":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Joined Case.caseStyle."},"billingEntityName":{"type":"object","nullable":true,"description":"Joined Case.billingEntity.name."},"balance":{"type":"string","description":"totalInvoice - totalPaid - writeOffs for this invoice."},"totalInvoice":{"type":"string","description":"totalFees + totalExpenses (rounded to cents)."},"totalFees":{"type":"string","description":"Sum of billable time-entry fee amounts."},"totalExpenses":{"type":"string","description":"Sum of billable expense cost*quantity, rounded to cents."},"totalHours":{"type":"string","description":"Sum of totalTime over billable time entries."},"previousBalance":{"type":"string","description":"Carried-forward balance of prior invoices (only when the billing entity shows outstanding invoices)."},"payments":{"type":"array","items":{"$ref":"#/components/schemas/InvoicePaymentDto"}},"totalPayments":{"type":"string","description":"Sum of fees + expenses paid (excludes write-offs)."},"writeOffs":{"type":"string","description":"Sum of fee + expense write-offs."},"grandTotal":{"type":"string","description":"(totalInvoice + previousBalance) - totalPayments - writeOffs."},"billingEntityContactName":{"type":"object","nullable":true,"description":"Billing-entity contact person/company name."},"fixedFee":{"nullable":true,"description":"The case's fixed fee and how much of it this invoice bills. Null when the case is not Fixed Fee and the invoice has no fixed-fee line.","type":"object","allOf":[{"$ref":"#/components/schemas/InvoiceFixedFeeDto"}]}},"required":["id","caseId","invoiceNumber","numberPrefix","displayNumber","invoiceDate","startDate","endDate","dueDate","datePaid","invoiceTermsId","invoiceStageId","invoiceStageName","description","isFixedFee","isManualInvoice","isFinal","creationTime","caseStyle","billingEntityName","balance","totalInvoice","totalFees","totalExpenses","totalHours","previousBalance","payments","totalPayments","writeOffs","grandTotal","billingEntityContactName","fixedFee"]},"CreateManualInvoiceDto":{"type":"object","properties":{"caseId":{"type":"number","description":"Case to invoice. It must have a billing entity."},"invoiceNumber":{"type":"number","description":"Invoice number (digits only; the tenant prefix is added for display). Omit to take the next number from the counter. Must never have been used before."},"invoiceDate":{"type":"string","description":"Invoice date (ISO)."},"invoiceTermsId":{"type":"number","description":"Invoice terms id; sets the due date when dueDate is omitted."},"startDate":{"type":"string","description":"Start of the billed period (ISO)."},"endDate":{"type":"string","description":"End of the billed period (ISO)."},"dueDate":{"type":"string","description":"Due date (ISO). Defaults to invoice date + terms days."},"fixedFeeAmount":{"type":"string","description":"Amount of the case's fixed fee to bill on this invoice (decimal string), only when the case's billing entity is Fixed Fee. Omitted or \"0\" bills none; to bill the fee on its own invoice use POST /invoices/fixed-fee.","example":"1250.00"},"isFixedFee":{"type":"boolean","description":"Fixed-fee invoice (time added to it keeps its entered rate)."},"isFinal":{"type":"boolean","description":"Final invoice; marks the case final so no new time can be added."},"invoiceStageId":{"type":"number","description":"Invoice stage id. Defaults to Open."},"description":{"type":"string"}},"required":["caseId","invoiceDate","startDate","endDate"]},"BatchInvoiceDto":{"type":"object","properties":{"caseIds":{"description":"Cases to bill in this run.","type":"array","items":{"type":"number"}},"startDate":{"type":"string","description":"Inclusive start of the billing period (yyyy-mm-dd)."},"endDate":{"type":"string","description":"Inclusive end of the billing period (yyyy-mm-dd)."},"includeUnapproved":{"type":"boolean","description":"Include unapproved time, as on a single pre-bill."}},"required":["caseIds","startDate","endDate"]},"BatchInvoiceResultItemDto":{"type":"object","properties":{"caseId":{"type":"number"},"ok":{"type":"boolean"},"invoiceId":{"type":"object","nullable":true},"invoiceNumber":{"type":"object","nullable":true},"displayNumber":{"type":"string","nullable":true,"description":"numberPrefix + invoiceNumber."},"error":{"type":"object","nullable":true,"description":"Reason this case was skipped, when ok=false."}},"required":["caseId","ok","invoiceId","invoiceNumber","displayNumber","error"]},"BatchInvoiceResultDto":{"type":"object","properties":{"requested":{"type":"number"},"succeeded":{"type":"number"},"failed":{"type":"number"},"results":{"type":"array","items":{"$ref":"#/components/schemas/BatchInvoiceResultItemDto"}}},"required":["requested","succeeded","failed","results"]},"UpdateInvoiceDto":{"type":"object","properties":{"invoiceStageId":{"type":"number","description":"Invoice stage id (1 Open .. 5 Partial Payment)."},"isFinal":{"type":"boolean","description":"Marks the invoice (and its case) final."},"invoiceTermsId":{"type":"number"},"dueDate":{"type":"string"},"datePaid":{"type":"string"},"description":{"type":"string"},"invoiceDate":{"type":"string","description":"Invoice date. Changing it with terms selected moves the due date."},"startDate":{"type":"string","description":"Start of the billed period."},"endDate":{"type":"string","description":"End of the billed period."},"isFixedFee":{"type":"boolean","description":"Fixed-fee invoice. When true, each time entry on the invoice is re-totalled as totalTime x its rate (legacy CreateOrUpdateInvoice)."},"fixedFeeAmount":{"type":"string","description":"Amount of the case's fixed fee billed on this invoice (decimal string). Only for a case whose billing entity is Fixed Fee. It may be any part of what is left of the fee, for instalments; \"0\" removes the fixed-fee line.","example":"1250.00"},"caseId":{"type":"number","description":"Move the invoice to another case. The case must have a billing entity. A fixed-fee line moves with the invoice, so the new case must be Fixed Fee with enough of its fee left."}}},"WebhookDto":{"type":"object","properties":{"id":{"type":"number"},"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"creationTime":{"type":"string"}},"required":["id","url","eventTypes","isActive","creationTime"]},"CreateWebhookDto":{"type":"object","properties":{"url":{"type":"string","example":"https://example.com/hooks/casewizard","description":"Public https URL. Private, loopback, link-local and internal hosts are rejected."},"eventTypes":{"type":"array","items":{"type":"string","enum":["case.created","case.updated","invoice.created","invoice.updated","payment.created","payment.updated"]}}},"required":["url","eventTypes"]},"CreatedWebhookDto":{"type":"object","properties":{"id":{"type":"number"},"url":{"type":"string"},"eventTypes":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"creationTime":{"type":"string"},"secret":{"type":"string","description":"HMAC signing secret. Shown once; verify deliveries with it."}},"required":["id","url","eventTypes","isActive","creationTime","secret"]},"UpdateWebhookDto":{"type":"object","properties":{"url":{"type":"string","description":"Public https URL. Private, loopback, link-local and internal hosts are rejected."},"eventTypes":{"type":"array","items":{"type":"string","enum":["case.created","case.updated","invoice.created","invoice.updated","payment.created","payment.updated"]}},"isActive":{"type":"boolean"}}},"PreBillDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"startDate":{"type":"object","nullable":true},"endDate":{"type":"object","nullable":true},"billingNotes":{"type":"object","nullable":true},"preBillNotes":{"type":"object","nullable":true},"invoiceId":{"type":"object","nullable":true,"description":"Set once an invoice is generated."},"timeEntryCount":{"type":"number","description":"Time entries attached to this pre-bill."},"creationTime":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Joined Case.caseStyle."},"caseKey":{"type":"number","nullable":true,"description":"Joined Case.caseKey: the case number shown in case URLs (GET /cases/key/{key})."},"billingEntityName":{"type":"object","nullable":true,"description":"Joined Case.billingEntity.name."},"totalHours":{"type":"string","description":"Sum of totalTime over attached pre-billed time entries."},"totalServices":{"type":"string","description":"Sum of fee amounts over attached billable time entries."},"totalExpenses":{"type":"string","description":"Sum of in-range billable expense cost*quantity, rounded to cents."},"totalAmount":{"type":"string","description":"totalServices + totalExpenses."}},"required":["id","caseId","startDate","endDate","billingNotes","preBillNotes","invoiceId","timeEntryCount","creationTime","caseStyle","caseKey","billingEntityName","totalHours","totalServices","totalExpenses","totalAmount"]},"PreBillListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PreBillDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"GeneratePreBillDto":{"type":"object","properties":{"caseId":{"type":"number"},"startDate":{"type":"string","example":"2026-05-01"},"endDate":{"type":"string","example":"2026-05-31"},"includeUnapproved":{"type":"boolean","default":false,"description":"Include time that is not yet Approved even when the tenant requires approval. Unapproved time is always included when the tenant billing setting bypassTimeEntryApproval is on (the legacy default)."}},"required":["caseId","startDate","endDate"]},"BatchPreBillDto":{"type":"object","properties":{"startDate":{"type":"string","example":"2026-05-01"},"endDate":{"type":"string","example":"2026-05-31"},"search":{"type":"string","description":"Match case style or billing entity name."},"includeUnapproved":{"type":"boolean","default":false,"description":"Include time that is not yet Approved."}},"required":["startDate","endDate"]},"BatchPreBillResultItemDto":{"type":"object","properties":{"caseId":{"type":"number"},"ok":{"type":"boolean"},"preBillId":{"type":"object","nullable":true},"error":{"type":"object","nullable":true,"description":"Reason this case was skipped, when ok=false."}},"required":["caseId","ok","preBillId","error"]},"BatchPreBillResultDto":{"type":"object","properties":{"requested":{"type":"number"},"succeeded":{"type":"number"},"failed":{"type":"number"},"results":{"type":"array","items":{"$ref":"#/components/schemas/BatchPreBillResultItemDto"}}},"required":["requested","succeeded","failed","results"]},"PreBillDetailDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"startDate":{"type":"object","nullable":true},"endDate":{"type":"object","nullable":true},"billingNotes":{"type":"object","nullable":true},"preBillNotes":{"type":"object","nullable":true},"invoiceId":{"type":"object","nullable":true,"description":"Set once an invoice is generated."},"timeEntryCount":{"type":"number","description":"Time entries attached to this pre-bill."},"creationTime":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Joined Case.caseStyle."},"caseKey":{"type":"number","nullable":true,"description":"Joined Case.caseKey: the case number shown in case URLs (GET /cases/key/{key})."},"billingEntityName":{"type":"object","nullable":true,"description":"Joined Case.billingEntity.name."},"totalHours":{"type":"string","description":"Sum of totalTime over attached pre-billed time entries."},"totalServices":{"type":"string","description":"Sum of fee amounts over attached billable time entries."},"totalExpenses":{"type":"string","description":"Sum of in-range billable expense cost*quantity, rounded to cents."},"totalAmount":{"type":"string","description":"totalServices + totalExpenses."},"billingEntityId":{"type":"object","nullable":true},"billingContactName":{"type":"object","nullable":true},"billingAddressLine1":{"type":"object","nullable":true},"billingAddressLine2":{"type":"object","nullable":true},"billingCity":{"type":"object","nullable":true},"billingStateCode":{"type":"object","nullable":true},"billingPostalCode":{"type":"object","nullable":true},"billingPhone":{"type":"object","nullable":true},"billingFax":{"type":"object","nullable":true},"billingContactNotes":{"type":"string","nullable":true,"description":"The bill-to contact's notes (person contact, else organization contact), shown as Notes on the worksheet bill-to block (legacy BillingEntityContactNotes)."},"fixedFeeToBill":{"type":"string","nullable":true,"description":"Deprecated: always null. The fixed fee is billed on its own invoice (POST /invoices/fixed-fee), not through a pre-bill.","deprecated":true}},"required":["id","caseId","startDate","endDate","billingNotes","preBillNotes","invoiceId","timeEntryCount","creationTime","caseStyle","caseKey","billingEntityName","totalHours","totalServices","totalExpenses","totalAmount","billingEntityId","billingContactName","billingAddressLine1","billingAddressLine2","billingCity","billingStateCode","billingPostalCode","billingPhone","billingFax","billingContactNotes","fixedFeeToBill"]},"UpdatePreBillDto":{"type":"object","properties":{"billingNotes":{"type":"string"},"preBillNotes":{"type":"string"}}},"DeletePreBillsDto":{"type":"object","properties":{"ids":{"description":"Pre-bill ids to delete.","type":"array","items":{"type":"number"}}},"required":["ids"]},"DeletePreBillFailureDto":{"type":"object","properties":{"id":{"type":"number"},"reason":{"type":"string","description":"Why it was not deleted (missing, or already invoiced)."}},"required":["id","reason"]},"DeletePreBillsResultDto":{"type":"object","properties":{"deletedIds":{"description":"Ids that were deleted.","type":"array","items":{"type":"number"}},"failed":{"type":"array","items":{"$ref":"#/components/schemas/DeletePreBillFailureDto"}}},"required":["deletedIds","failed"]},"BillingSettingsDto":{"type":"object","properties":{"defaultRateTypeId":{"type":"object","nullable":true},"defaultBillingRate":{"type":"object","nullable":true},"invoiceTermsId":{"type":"object","nullable":true},"invoiceDueDays":{"type":"object","nullable":true},"invoicePrefix":{"type":"string","nullable":true},"nextInvoiceNumber":{"type":"number","nullable":true,"description":"Stored counter (null until the first invoice or an explicit setting)."},"effectiveNextInvoiceNumber":{"type":"number","description":"The number the next invoice will actually get: max(nextInvoiceNumber, highest used + 1), or 10000 when no invoice exists yet."},"maxUsedInvoiceNumber":{"type":"number","nullable":true,"description":"Highest invoice number ever used by the tenant (soft-deleted invoices included)."},"invoiceFooter":{"type":"object","nullable":true},"bypassTimeEntryApproval":{"type":"boolean","description":"When true, Billables and pre-bills include time that has not been approved."}},"required":["defaultRateTypeId","defaultBillingRate","invoiceTermsId","invoiceDueDays","invoicePrefix","nextInvoiceNumber","effectiveNextInvoiceNumber","maxUsedInvoiceNumber","invoiceFooter","bypassTimeEntryApproval"]},"UpdateBillingSettingsDto":{"type":"object","properties":{"defaultRateTypeId":{"type":"number","description":"Default rate type id for new billing entities."},"defaultBillingRate":{"type":"string","description":"Default hourly billing rate (decimal string)."},"invoiceTermsId":{"type":"number","description":"Default invoice terms id."},"invoiceDueDays":{"type":"number","description":"Default net days until an invoice is due."},"invoicePrefix":{"type":"string","description":"Printed before the invoice number on new invoices (up to 10 letters, digits or dashes; \"\" clears it). Invoices already issued keep the prefix they were issued with.","maxLength":10},"nextInvoiceNumber":{"type":"number","description":"Next invoice number to assign. Cannot be lower than the highest invoice number already used + 1. A tenant with no invoices starts at 10000."},"invoiceFooter":{"type":"string","description":"Default footer text printed on invoices."},"bypassTimeEntryApproval":{"type":"boolean","description":"When true, unapproved time is billable without Time Sheets submit/approve (legacy BypassTimeEntrySubmissionAndApproval)."}}},"StatementDto":{"type":"object","properties":{"id":{"type":"number"},"billingEntityId":{"type":"number"},"statementDate":{"format":"date-time","type":"string"},"startDate":{"format":"date-time","type":"string"},"endDate":{"format":"date-time","type":"string"},"totalBilled":{"type":"string","description":"Total billed in the period (decimal string)."},"totalCollected":{"type":"string","description":"Total collected in the period (decimal string)."},"totalWriteOff":{"type":"string","description":"Total written off in the period (decimal string)."},"balance":{"type":"string","description":"Outstanding balance (decimal string)."},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","billingEntityId","statementDate","startDate","endDate","totalBilled","totalCollected","totalWriteOff","balance","notes","creationTime"]},"StatementListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/StatementDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"GenerateStatementDto":{"type":"object","properties":{"billingEntityId":{"type":"number","description":"Billing entity the statement is for."},"startDate":{"type":"string","example":"2026-01-01"},"endDate":{"type":"string","example":"2026-03-31"},"notes":{"type":"string"}},"required":["billingEntityId","startDate","endDate"]},"StatementByCaseRowDto":{"type":"object","properties":{"totalBilled":{"type":"string","description":"Sum of invoice totals, fees + expenses (decimal string)."},"totalPaid":{"type":"string","description":"Sum paid, excluding write-offs (decimal string)."},"totalWriteOff":{"type":"string","description":"Sum of fee + expense write-offs (decimal string)."},"balance":{"type":"string","description":"totalBilled - totalPaid - totalWriteOff (decimal string)."},"current":{"type":"string","description":"Balance 30 or fewer days past due, including not yet due (decimal string)."},"days31To60":{"type":"string","description":"Balance 31-60 days past due (decimal string)."},"days61To90":{"type":"string","description":"Balance 61-90 days past due (decimal string)."},"days91Plus":{"type":"string","description":"Balance 91 or more days past due (decimal string)."},"caseId":{"type":"number"},"caseKey":{"type":"number","nullable":true,"description":"The case number shown in case URLs (Case.caseKey)."},"caseNumber":{"type":"string"},"caseStyle":{"type":"string","nullable":true},"billingEntityId":{"type":"number"},"billingEntityName":{"type":"string","nullable":true},"invoiceCount":{"type":"number","description":"Invoices included in this row (after the balanceDue filter)."}},"required":["totalBilled","totalPaid","totalWriteOff","balance","current","days31To60","days61To90","days91Plus","caseId","caseKey","caseNumber","caseStyle","billingEntityId","billingEntityName","invoiceCount"]},"StatementByCaseTotalsDto":{"type":"object","properties":{"totalBilled":{"type":"string","description":"Sum of invoice totals, fees + expenses (decimal string)."},"totalPaid":{"type":"string","description":"Sum paid, excluding write-offs (decimal string)."},"totalWriteOff":{"type":"string","description":"Sum of fee + expense write-offs (decimal string)."},"balance":{"type":"string","description":"totalBilled - totalPaid - totalWriteOff (decimal string)."},"current":{"type":"string","description":"Balance 30 or fewer days past due, including not yet due (decimal string)."},"days31To60":{"type":"string","description":"Balance 31-60 days past due (decimal string)."},"days61To90":{"type":"string","description":"Balance 61-90 days past due (decimal string)."},"days91Plus":{"type":"string","description":"Balance 91 or more days past due (decimal string)."}},"required":["totalBilled","totalPaid","totalWriteOff","balance","current","days31To60","days61To90","days91Plus"]},"StatementsByCaseResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/StatementByCaseRowDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"},"totals":{"description":"Grand totals over every matching case, not just this page.","allOf":[{"$ref":"#/components/schemas/StatementByCaseTotalsDto"}]},"statementDate":{"format":"date-time","type":"string","description":"The as-of date the aging was computed for."}},"required":["items","meta","totals","statementDate"]},"CaseStatementInvoiceDto":{"type":"object","properties":{"invoiceId":{"type":"number"},"invoiceNumber":{"type":"number","description":"Numeric invoice number."},"displayNumber":{"type":"string","description":"Number shown to people: numberPrefix + invoiceNumber."},"invoiceDate":{"format":"date-time","type":"string"},"dueDate":{"format":"date-time","type":"string","description":"Due date, or the invoice date when the invoice has none."},"totalInvoice":{"type":"string","description":"Fees + expenses (decimal string)."},"totalPaid":{"type":"string","description":"Fees + expenses paid, excluding write-offs (decimal string)."},"totalWriteOff":{"type":"string","description":"Fee + expense write-offs (decimal string)."},"balance":{"type":"string","description":"totalInvoice - totalPaid - totalWriteOff (decimal string)."},"daysPastDue":{"type":"number","description":"Whole days past the due date on the as-of date (negative when not yet due)."},"agingBucket":{"type":"string","enum":["current","days31To60","days61To90","days91Plus"]},"current":{"type":"string","description":"Balance when 30 or fewer days past due (decimal string)."},"days31To60":{"type":"string","description":"Balance when 31-60 days past due (decimal string)."},"days61To90":{"type":"string","description":"Balance when 61-90 days past due (decimal string)."},"days91Plus":{"type":"string","description":"Balance when 91 or more days past due (decimal string)."}},"required":["invoiceId","invoiceNumber","displayNumber","invoiceDate","dueDate","totalInvoice","totalPaid","totalWriteOff","balance","daysPastDue","agingBucket","current","days31To60","days61To90","days91Plus"]},"CaseStatementDto":{"type":"object","properties":{"caseId":{"type":"number"},"caseStyle":{"type":"string","nullable":true},"billingEntityId":{"type":"number","nullable":true},"billingEntityName":{"type":"string","nullable":true},"statementDate":{"format":"date-time","type":"string","description":"The as-of date the statement was computed for."},"invoices":{"type":"array","items":{"$ref":"#/components/schemas/CaseStatementInvoiceDto"}},"totalInvoice":{"type":"string","description":"Sum of totalInvoice (decimal string)."},"totalPaid":{"type":"string","description":"Sum of totalPaid (decimal string)."},"totalWriteOff":{"type":"string","description":"Sum of totalWriteOff (decimal string)."},"balanceDue":{"type":"string","description":"Total balance due (decimal string)."},"totalCurrent":{"type":"string","description":"Sum of the Current bucket (decimal string)."},"total31To60":{"type":"string","description":"Sum of the 31-60 bucket (decimal string)."},"total61To90":{"type":"string","description":"Sum of the 61-90 bucket (decimal string)."},"total91Plus":{"type":"string","description":"Sum of the 91+ bucket (decimal string)."}},"required":["caseId","caseStyle","billingEntityId","billingEntityName","statementDate","invoices","totalInvoice","totalPaid","totalWriteOff","balanceDue","totalCurrent","total31To60","total61To90","total91Plus"]},"BilledCollectedClientDto":{"type":"object","properties":{"billingEntityId":{"type":"number"},"clientName":{"type":"string","nullable":true},"feesBilled":{"type":"string"},"expensesBilled":{"type":"string"},"totalBilled":{"type":"string"},"feesCollected":{"type":"string"},"expensesCollected":{"type":"string"},"totalCollected":{"type":"string"},"writeOff":{"type":"string"},"balance":{"type":"string"}},"required":["billingEntityId","clientName","feesBilled","expensesBilled","totalBilled","feesCollected","expensesCollected","totalCollected","writeOff","balance"]},"BilledCollectedReportDto":{"type":"object","properties":{"clients":{"type":"array","items":{"$ref":"#/components/schemas/BilledCollectedClientDto"}},"attorneyName":{"type":"string","nullable":true,"description":"Name of the attorney the report was filtered to, if any."},"totalFeesBilled":{"type":"string"},"totalExpensesBilled":{"type":"string"},"grandTotalBilled":{"type":"string"},"totalFeesCollected":{"type":"string"},"totalExpensesCollected":{"type":"string"},"grandTotalCollected":{"type":"string"},"grandTotalWriteOff":{"type":"string"},"grandTotalBalance":{"type":"string"}},"required":["clients","attorneyName","totalFeesBilled","totalExpensesBilled","grandTotalBilled","totalFeesCollected","totalExpensesCollected","grandTotalCollected","grandTotalWriteOff","grandTotalBalance"]},"BilledCollectedRowDto":{"type":"object","properties":{"id":{"type":"number","description":"Deterministic key (the invoice id)."},"invoiceId":{"type":"number"},"caseId":{"type":"number"},"billingEntityId":{"type":"number"},"billingEntityName":{"type":"string","nullable":true},"invoiceNumber":{"type":"number"},"displayNumber":{"type":"string","description":"Invoice prefix + number, as shown to people."},"invoiceDate":{"format":"date-time","type":"string"},"dueDate":{"format":"date-time","type":"string","description":"dueDate, falling back to invoiceDate."},"caseStyle":{"type":"string","nullable":true,"description":"Case label (case number)."},"totalFees":{"type":"string"},"totalExpenses":{"type":"string"},"totalInvoice":{"type":"string"},"totalFeesPaid":{"type":"string"},"totalExpensesPaid":{"type":"string"},"feesWriteOff":{"type":"string"},"expensesWriteOff":{"type":"string"},"totalWriteOff":{"type":"string"},"totalPaid":{"type":"string","description":"totalFeesPaid + totalExpensesPaid (excludes write-offs)."},"balance":{"type":"string","description":"totalInvoice - totalPaid - totalWriteOff."}},"required":["id","invoiceId","caseId","billingEntityId","billingEntityName","invoiceNumber","displayNumber","invoiceDate","dueDate","caseStyle","totalFees","totalExpenses","totalInvoice","totalFeesPaid","totalExpensesPaid","feesWriteOff","expensesWriteOff","totalWriteOff","totalPaid","balance"]},"CollectionsMonthDto":{"type":"object","properties":{"hours":{"type":"string","description":"Hours (2 dp). Payment basis: scaled by the payment share."},"feesBilled":{"type":"string","description":"The timekeeper's own billable, non-held fees."},"expensesBilled":{"type":"string","description":"Invoice expenses times attorneyFees / invoiceFees."},"billed":{"type":"string","description":"feesBilled + expensesBilled."},"feesCollected":{"type":"string","description":"Fees paid times attorneyFees / invoiceFees."},"expensesCollected":{"type":"string","description":"Expenses paid times attorneyFees / invoiceFees."},"collected":{"type":"string","description":"feesCollected + expensesCollected."},"year":{"type":"number"},"month":{"type":"number","description":"Month 1-12 (UTC): invoice month or payment month by basis."}},"required":["hours","feesBilled","expensesBilled","billed","feesCollected","expensesCollected","collected","year","month"]},"CollectionsFiguresDto":{"type":"object","properties":{"hours":{"type":"string","description":"Hours (2 dp). Payment basis: scaled by the payment share."},"feesBilled":{"type":"string","description":"The timekeeper's own billable, non-held fees."},"expensesBilled":{"type":"string","description":"Invoice expenses times attorneyFees / invoiceFees."},"billed":{"type":"string","description":"feesBilled + expensesBilled."},"feesCollected":{"type":"string","description":"Fees paid times attorneyFees / invoiceFees."},"expensesCollected":{"type":"string","description":"Expenses paid times attorneyFees / invoiceFees."},"collected":{"type":"string","description":"feesCollected + expensesCollected."}},"required":["hours","feesBilled","expensesBilled","billed","feesCollected","expensesCollected","collected"]},"AttorneyCollectionsDto":{"type":"object","properties":{"userId":{"type":"number","description":"Timekeeper user id."},"firstName":{"type":"string","nullable":true},"lastName":{"type":"string","nullable":true},"months":{"description":"Newest month first.","type":"array","items":{"$ref":"#/components/schemas/CollectionsMonthDto"}},"totals":{"$ref":"#/components/schemas/CollectionsFiguresDto"}},"required":["userId","firstName","lastName","months","totals"]},"CollectionsByAttorneyReportDto":{"type":"object","properties":{"basis":{"type":"string","enum":["invoiceDate","paymentDate"]},"attorneys":{"type":"array","items":{"$ref":"#/components/schemas/AttorneyCollectionsDto"}},"grandTotals":{"$ref":"#/components/schemas/CollectionsFiguresDto"}},"required":["basis","attorneys","grandTotals"]},"PaymentsReportRowDto":{"type":"object","properties":{"paymentId":{"type":"number"},"invoiceId":{"type":"number"},"clientName":{"type":"string","nullable":true},"caseStyle":{"type":"string","nullable":true},"paymentDate":{"format":"date-time","type":"string"},"invoiceNumber":{"type":"number"},"displayNumber":{"type":"string","description":"Invoice prefix + number, as shown to people."},"invoiceDate":{"format":"date-time","type":"string"},"checkNumber":{"type":"string","nullable":true},"paymentAmount":{"type":"string","description":"feesPaid + expensesPaid, each null counted as 0."}},"required":["paymentId","invoiceId","clientName","caseStyle","paymentDate","invoiceNumber","displayNumber","invoiceDate","checkNumber","paymentAmount"]},"PaymentsReportGroupDto":{"type":"object","properties":{"year":{"type":"number"},"month":{"type":"number","description":"Month 1-12 (UTC)."},"period":{"type":"string","description":"Display label, e.g. \"September 2026\"."},"payments":{"type":"array","items":{"$ref":"#/components/schemas/PaymentsReportRowDto"}},"totalPaymentAmount":{"type":"string"}},"required":["year","month","period","payments","totalPaymentAmount"]},"PaymentsReportDto":{"type":"object","properties":{"groupedBy":{"type":"string","enum":["invoiceDate","paymentDate"],"description":"invoiceDate when an invoice-date bound was given, otherwise paymentDate."},"groups":{"description":"Oldest month first.","type":"array","items":{"$ref":"#/components/schemas/PaymentsReportGroupDto"}},"totalPaymentAmount":{"type":"string"}},"required":["groupedBy","groups","totalPaymentAmount"]},"AgingInvoiceDto":{"type":"object","properties":{"invoiceNumber":{"type":"number"},"displayNumber":{"type":"string","description":"Invoice prefix + number, as shown to people."},"invoiceDate":{"format":"date-time","type":"string"},"dueDate":{"format":"date-time","type":"string"},"caseStyle":{"type":"string","nullable":true},"thirty":{"type":"string","description":"0-30 days past due."},"sixty":{"type":"string","description":"31-60 days past due."},"ninety":{"type":"string","description":"61-90 days past due."},"ninetyPlus":{"type":"string","description":"91+ days past due."},"totalAging":{"type":"string"}},"required":["invoiceNumber","displayNumber","invoiceDate","dueDate","caseStyle","thirty","sixty","ninety","ninetyPlus","totalAging"]},"AgingClientDto":{"type":"object","properties":{"billingEntityId":{"type":"number"},"name":{"type":"string","nullable":true},"invoices":{"type":"array","items":{"$ref":"#/components/schemas/AgingInvoiceDto"}},"totalThirty":{"type":"string"},"totalSixty":{"type":"string"},"totalNinety":{"type":"string"},"totalNinetyPlus":{"type":"string"},"totalAging":{"type":"string"}},"required":["billingEntityId","name","invoices","totalThirty","totalSixty","totalNinety","totalNinetyPlus","totalAging"]},"ArAgingReportDto":{"type":"object","properties":{"clients":{"type":"array","items":{"$ref":"#/components/schemas/AgingClientDto"}},"grandTotalThirty":{"type":"string"},"grandTotalSixty":{"type":"string"},"grandTotalNinety":{"type":"string"},"grandTotalNinetyPlus":{"type":"string"},"grandTotalAging":{"type":"string"}},"required":["clients","grandTotalThirty","grandTotalSixty","grandTotalNinety","grandTotalNinetyPlus","grandTotalAging"]},"AuditSummaryChangeDto":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}},"required":["label","value"]},"AuditSummaryDto":{"type":"object","properties":{"headline":{"type":"string"},"changes":{"type":"array","items":{"$ref":"#/components/schemas/AuditSummaryChangeDto"}}},"required":["headline","changes"]},"AuditLogDto":{"type":"object","properties":{"id":{"type":"string"},"actorUserId":{"type":"object","nullable":true},"actorType":{"type":"string"},"actorLabel":{"type":"object","nullable":true},"action":{"type":"string"},"resource":{"type":"object","nullable":true},"path":{"type":"string"},"entityId":{"type":"object","nullable":true},"statusCode":{"type":"object","nullable":true},"requestId":{"type":"object","nullable":true},"durationMs":{"type":"object","nullable":true,"description":"Request duration in milliseconds."},"ipAddress":{"type":"object","nullable":true},"location":{"type":"object","nullable":true,"description":"Best-effort geo from proxy headers."},"browserInfo":{"type":"object","nullable":true,"description":"Parsed browser / OS summary."},"userAgent":{"type":"object","nullable":true},"clientName":{"type":"object","nullable":true},"parameters":{"type":"object","nullable":true,"description":"Sanitized request snapshot (params/query/body) and optional response summary.","additionalProperties":true},"summary":{"nullable":true,"description":"Human-readable summary with resolved entity names.","type":"object","allOf":[{"$ref":"#/components/schemas/AuditSummaryDto"}]},"exception":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","actorUserId","actorType","actorLabel","action","resource","path","entityId","statusCode","requestId","durationMs","ipAddress","location","browserInfo","userAgent","clientName","parameters","summary","exception","creationTime"]},"AuditLogListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AuditLogDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"MicrosoftConnectionDto":{"type":"object","properties":{"connected":{"type":"boolean","description":"Whether this user has a usable Microsoft connection."},"email":{"type":"object","description":"Microsoft account the connection was made with."},"entraTenantId":{"type":"object","description":"Entra tenant (tid) the connection belongs to."},"scopes":{"description":"Delegated scopes Microsoft actually granted.","type":"array","items":{"type":"string"}},"connectedAt":{"type":"object","description":"When the account was first connected."},"lastRefreshAt":{"type":"object","description":"When the token was last successfully refreshed."},"lastError":{"type":"object","description":"Why the connection stopped working (expired, consent revoked, Conditional Access). Present with connected=false when a connection exists but is unusable, which the UI should present as \"reconnect\" rather than \"set up\"."}},"required":["connected"]},"AuthorizeUrlRequestDto":{"type":"object","properties":{"returnTo":{"type":"string","description":"App-relative path to return to after a successful connect, e.g. /cases/1042. Rejected unless it is a same-site path, so it cannot be used as an open redirect.","example":"/cases/1042"}}},"AuthorizeUrlDto":{"type":"object","properties":{"authorizeUrl":{"type":"string","description":"Send the browser here with window.location.assign. Returned as JSON rather than a 302 because the web app proxies API calls with redirect:\"manual\", so a redirect would not be followed."}},"required":["authorizeUrl"]},"MicrosoftCallbackDto":{"type":"object","properties":{"code":{"type":"string","description":"Authorization code from the Entra redirect."},"state":{"type":"string","description":"Opaque state issued by /authorize-url. Single-use."}},"required":["code","state"]},"MicrosoftCallbackResultDto":{"type":"object","properties":{"connection":{"$ref":"#/components/schemas/MicrosoftConnectionDto"},"returnTo":{"type":"object","description":"Validated app-relative path the user should return to."}},"required":["connection"]},"EgnyteConnectionDto":{"type":"object","properties":{"connected":{"type":"boolean"},"email":{"type":"object"},"egnyteDomain":{"type":"object"},"scopes":{"type":"array","items":{"type":"string"}},"connectedAt":{"type":"object"},"lastRefreshAt":{"type":"object"},"lastError":{"type":"object"}},"required":["connected"]},"EgnyteAuthorizeUrlRequestDto":{"type":"object","properties":{"returnTo":{"type":"string","maxLength":512},"domain":{"type":"string","description":"Egnyte subdomain to connect. Saved to the firm settings before OAuth when it differs from the current domain, which requires Integrations.Manage.","maxLength":1024}}},"EgnyteAuthorizeUrlDto":{"type":"object","properties":{"authorizeUrl":{"type":"string"}},"required":["authorizeUrl"]},"EgnyteCallbackDto":{"type":"object","properties":{"code":{"type":"string","maxLength":4096},"state":{"type":"string","maxLength":128}},"required":["code","state"]},"EgnyteCallbackResultDto":{"type":"object","properties":{"connection":{"$ref":"#/components/schemas/EgnyteConnectionDto"},"returnTo":{"type":"object"}},"required":["connection"]},"UserManagementSettingsDto":{"type":"object","properties":{"allowSelfRegistration":{"type":"boolean","description":"When true, users may self-register into this tenant via POST /auth/register."},"isEmailConfirmationRequiredForLogin":{"type":"boolean","description":"When true, login requires Identity.emailConfirmed for this tenant."},"isTwoFactorLoginEnabled":{"type":"boolean","description":"When true, login requires authenticator TOTP (Identity.mfaEnabled) for this tenant."},"isEmailProviderEnabled":{"type":"boolean","description":"Reserved for future email OTP 2FA. Authenticator TOTP is the only channel today."}},"required":["allowSelfRegistration","isEmailConfirmationRequiredForLogin","isTwoFactorLoginEnabled","isEmailProviderEnabled"]},"UpdateUserManagementSettingsDto":{"type":"object","properties":{"allowSelfRegistration":{"type":"boolean"},"isEmailConfirmationRequiredForLogin":{"type":"boolean"},"isTwoFactorLoginEnabled":{"type":"boolean"},"isEmailProviderEnabled":{"type":"boolean"}},"required":["allowSelfRegistration","isEmailConfirmationRequiredForLogin","isTwoFactorLoginEnabled","isEmailProviderEnabled"]},"VersionDto":{"type":"object","properties":{"version":{"type":"string","example":"1.4.0"},"gitSha":{"type":"string","example":"3a9c1f2"},"buildTime":{"type":"object","nullable":true,"example":"2026-06-03T00:00:00Z"}},"required":["version","gitSha","buildTime"]},"CaseTypeTabsDto":{"type":"object","properties":{"caseTypeId":{"type":"number"},"liens":{"type":"boolean"},"injuries":{"type":"boolean","description":"Injuries tab. Legacy also required a plaintiff on the case before showing it."},"medicalExpenses":{"type":"boolean","description":"Medical Expenses tab. Legacy also required a plaintiff on the case before showing it."},"settlements":{"type":"boolean"},"criminalCharges":{"type":"boolean"},"victims":{"type":"boolean"},"arrestingOfficers":{"type":"boolean","description":"Arresting Officers tab. Legacy hard-coded it to case type id 6 (Constitutional), a bug; it is seeded for Criminal (11), the intended case type."},"plaintiffInjuries":{"type":"boolean","description":"Plaintiff page: Injuries section (legacy PlaintiffTabs)."},"plaintiffMedication":{"type":"boolean","description":"Plaintiff page: Medication section (legacy PlaintiffTabs)."},"plaintiffDoctors":{"type":"boolean","description":"Plaintiff page: Doctors section (legacy PlaintiffTabs)."},"plaintiffSubrogor":{"type":"boolean","description":"Plaintiff page: Subrogor section (legacy PlaintiffTabs)."},"plaintiffPatientHistory":{"type":"boolean","description":"Plaintiff page: Patient History section (legacy PlaintiffTabs)."},"plaintiffInsurance":{"type":"boolean","description":"Plaintiff page: Insurance section (legacy PlaintiffTabs)."}},"required":["caseTypeId","liens","injuries","medicalExpenses","settlements","criminalCharges","victims","arrestingOfficers","plaintiffInjuries","plaintiffMedication","plaintiffDoctors","plaintiffSubrogor","plaintiffPatientHistory","plaintiffInsurance"]},"CaseDto":{"type":"object","properties":{"id":{"type":"number"},"caseKey":{"type":"number","description":"The number people know the case by: the legacy case id for migrated cases, otherwise the id. Used in case URLs and as the document folder name; resolve it with GET /cases/key/{key}."},"caseNumber":{"type":"string"},"caseStyle":{"type":"object","nullable":true},"caseTypeId":{"type":"object","nullable":true},"caseTypeName":{"type":"object","nullable":true},"plaintiff":{"type":"object","nullable":true},"defendant":{"type":"object","nullable":true},"insurer":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"isFinal":{"type":"boolean"},"attorneyOfRecordUserId":{"type":"object","nullable":true},"attorneyOfRecordName":{"type":"object","nullable":true},"assignedToUserId":{"type":"object","nullable":true},"assignedToName":{"type":"object","nullable":true},"secondaryUserId":{"type":"object","nullable":true},"secondaryUserName":{"type":"object","nullable":true},"statutoryDeadline":{"type":"object","nullable":true},"remarks":{"type":"object","nullable":true},"billingEntityId":{"type":"object","nullable":true},"matterId":{"type":"object","nullable":true},"internalMatterId":{"type":"object","nullable":true},"clientMatterId":{"type":"object","nullable":true},"showTimekeeper":{"type":"boolean"},"invoiceBillingNotes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"lastModificationTime":{"type":"object","nullable":true},"tabs":{"nullable":true,"description":"Tab configuration of the case's type. Null when the case has no type or the type has no tab configuration (a firm-added type); legacy then showed none of the optional tabs.","type":"object","allOf":[{"$ref":"#/components/schemas/CaseTypeTabsDto"}]}},"required":["id","caseKey","caseNumber","caseStyle","caseTypeId","caseTypeName","plaintiff","defendant","insurer","isActive","isFinal","attorneyOfRecordUserId","attorneyOfRecordName","assignedToUserId","assignedToName","secondaryUserId","secondaryUserName","statutoryDeadline","remarks","billingEntityId","matterId","internalMatterId","clientMatterId","showTimekeeper","invoiceBillingNotes","creationTime","lastModificationTime","tabs"]},"CaseListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CaseDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateCaseDto":{"type":"object","properties":{"caseNumber":{"type":"string","example":"2026-PI-0001"},"caseStyle":{"type":"string","example":"Smith v. Jones"},"statutoryDeadline":{"type":"string","nullable":true,"description":"Statute-of-limitations deadline (ISO 8601). Null means no deadline."},"caseTypeId":{"type":"number"},"isActive":{"type":"boolean","default":true},"attorneyOfRecordUserId":{"type":"string"},"assignedToUserId":{"type":"string","description":"Primary assigned user id, distinct from the attorney of record."},"secondaryUserId":{"type":"string","description":"Secondary assigned user id, distinct from the attorney of record."},"remarks":{"type":"string"},"billingEntityId":{"type":"number","description":"Billing entity responsible for this case."},"matterId":{"type":"string","maxLength":128,"description":"Client-facing matter id printed on invoices."},"internalMatterId":{"type":"number","description":"Case detail field used as the internal matter number on invoices."},"clientMatterId":{"type":"number","description":"Case detail field used as the client matter number on invoices."},"showTimekeeper":{"type":"boolean","description":"Print the timekeeper on invoices (defaults to false)."},"invoiceBillingNotes":{"type":"string","description":"Notes surfaced during invoicing."}},"required":["caseNumber"]},"CaseTypeDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"CaseSummaryClassDto":{"type":"object","properties":{"id":{"type":"number"},"caseTypeId":{"type":"number"},"name":{"type":"string","description":"Tile component key (plaintiff, defendant, insurer, judges, ...)."},"label":{"type":"string","nullable":true,"description":"Tile caption (e.g. Claimant)."},"sortOrder":{"type":"number"},"personRoleId":{"type":"number","nullable":true,"description":"Constrains the tile to participants with this person role (Criminal judge tiles)."}},"required":["id","caseTypeId","name","label","sortOrder","personRoleId"]},"UpdateCaseDto":{"type":"object","properties":{"caseNumber":{"type":"string"},"caseStyle":{"type":"string","example":"Smith v. Jones"},"statutoryDeadline":{"type":"string","nullable":true,"description":"Statute-of-limitations deadline (ISO 8601). Null means no deadline."},"caseTypeId":{"type":"number"},"isActive":{"type":"boolean"},"isFinal":{"type":"boolean"},"attorneyOfRecordUserId":{"type":"string"},"assignedToUserId":{"type":"string","description":"Primary assigned user id, distinct from the attorney of record."},"secondaryUserId":{"type":"string","description":"Secondary assigned user id, distinct from the attorney of record."},"remarks":{"type":"string"},"billingEntityId":{"type":"number","description":"Billing entity responsible for this case."},"matterId":{"type":"string","maxLength":128,"description":"Client-facing matter id printed on invoices."},"internalMatterId":{"type":"number","nullable":true,"description":"Case detail field used as the internal matter number on invoices. Send null to clear it."},"clientMatterId":{"type":"number","nullable":true,"description":"Case detail field used as the client matter number on invoices. Send null to clear it."},"showTimekeeper":{"type":"boolean","description":"Print the timekeeper on invoices."},"invoiceBillingNotes":{"type":"string","description":"Notes surfaced during invoicing."}}},"PhoneDto":{"type":"object","properties":{"id":{"type":"number"},"phoneType":{"type":"string","enum":["OFFICE","CELL","HOME","FAX"]},"number":{"type":"string"},"extension":{"type":"object","nullable":true},"isPrimary":{"type":"boolean"}},"required":["id","phoneType","number","extension","isPrimary"]},"AddressDto":{"type":"object","properties":{"id":{"type":"number"},"addressType":{"type":"string","enum":["MAILING","PHYSICAL"]},"line1":{"type":"object","nullable":true},"line2":{"type":"object","nullable":true},"city":{"type":"object","nullable":true},"stateId":{"type":"object","nullable":true},"postalCode":{"type":"object","nullable":true},"isPrimary":{"type":"boolean"}},"required":["id","addressType","line1","line2","city","stateId","postalCode","isPrimary"]},"ContactDto":{"type":"object","properties":{"id":{"type":"number"},"email":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"phones":{"type":"array","items":{"$ref":"#/components/schemas/PhoneDto"}},"addresses":{"type":"array","items":{"$ref":"#/components/schemas/AddressDto"}}},"required":["id","email","notes","phones","addresses"]},"PersonDto":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"ssn":{"type":"object","nullable":true,"description":"Masked by default (e.g. ***-**-6789). Use GET /people/{id}/pii to reveal."},"driversLicense":{"type":"object","nullable":true,"description":"Masked by default. Use the reveal endpoint."},"personTypeId":{"type":"object","nullable":true},"middleName":{"type":"object","nullable":true},"genderId":{"type":"object","nullable":true},"dateOfBirth":{"type":"object","nullable":true,"description":"Date of birth (date only)."},"driversLicenseStateId":{"type":"object","nullable":true},"yearsSchooling":{"type":"object","nullable":true},"highSchoolGrad":{"type":"object","nullable":true},"highSchoolName":{"type":"object","nullable":true},"yearsCollege":{"type":"object","nullable":true},"collegeGrad":{"type":"object","nullable":true},"collegeName":{"type":"object","nullable":true},"gradePointAvg":{"type":"object","nullable":true,"description":"Decimal string, e.g. \"3.50\"."},"contact":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/ContactDto"}]},"creationTime":{"format":"date-time","type":"string"}},"required":["id","firstName","lastName","ssn","driversLicense","personTypeId","middleName","genderId","dateOfBirth","driversLicenseStateId","yearsSchooling","highSchoolGrad","highSchoolName","yearsCollege","collegeGrad","collegeName","gradePointAvg","contact","creationTime"]},"PersonListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PersonDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreatePhoneDto":{"type":"object","properties":{"phoneType":{"type":"string","enum":["OFFICE","CELL","HOME","FAX"]},"number":{"type":"string"},"extension":{"type":"string"},"isPrimary":{"type":"boolean"}},"required":["phoneType","number"]},"CreateAddressDto":{"type":"object","properties":{"addressType":{"type":"string","enum":["MAILING","PHYSICAL"]},"line1":{"type":"string"},"line2":{"type":"string"},"city":{"type":"string"},"stateId":{"type":"number"},"postalCode":{"type":"string"},"isPrimary":{"type":"boolean"}},"required":["addressType"]},"CreateContactDto":{"type":"object","properties":{"email":{"type":"string"},"notes":{"type":"string"},"phones":{"type":"array","items":{"$ref":"#/components/schemas/CreatePhoneDto"}},"addresses":{"type":"array","items":{"$ref":"#/components/schemas/CreateAddressDto"}}}},"CreatePersonDto":{"type":"object","properties":{"middleName":{"type":"string","nullable":true,"description":"Null clears it on update."},"genderId":{"type":"number","nullable":true,"description":"Gender lookup id (GET /lookups/genders). Null clears it on update."},"dateOfBirth":{"type":"string","nullable":true,"description":"Date of birth (ISO 8601 date). Null clears it on update."},"driversLicenseStateId":{"type":"number","nullable":true,"description":"Issuing state of the drivers license (GET /lookups/states). Null clears it on update."},"yearsSchooling":{"type":"number","nullable":true,"description":"Years of high school completed. Null clears it on update."},"highSchoolGrad":{"type":"boolean","nullable":true,"description":"Null clears it on update."},"highSchoolName":{"type":"string","nullable":true,"description":"Null clears it on update."},"yearsCollege":{"type":"number","nullable":true,"description":"Years of college completed. Null clears it on update."},"collegeGrad":{"type":"boolean","nullable":true,"description":"Null clears it on update."},"collegeName":{"type":"string","nullable":true,"description":"Null clears it on update."},"gradePointAvg":{"type":"string","nullable":true,"description":"Grade point average (decimal string, e.g. \"3.50\"). Null clears it on update."},"firstName":{"type":"string"},"lastName":{"type":"string"},"ssn":{"type":"string","description":"Digits only; non-digits are stripped on save."},"driversLicense":{"type":"string"},"personTypeId":{"type":"number"},"contact":{"$ref":"#/components/schemas/CreateContactDto"}},"required":["firstName","lastName"]},"PersonPiiDto":{"type":"object","properties":{"id":{"type":"string"},"ssn":{"type":"object","nullable":true,"description":"Plaintext, digits only."},"driversLicense":{"type":"object","nullable":true,"description":"Plaintext."}},"required":["id","ssn","driversLicense"]},"ContactUsageCaseDto":{"type":"object","properties":{"caseId":{"type":"number"},"caseNumber":{"type":"string"},"caseStyle":{"type":"string","nullable":true},"caseKey":{"type":"number","description":"The case number shown in case URLs (Case.caseKey)."},"roles":{"description":"Readable roles, e.g. \"Plaintiff\", \"Victim\".","type":"array","items":{"type":"string"}}},"required":["caseId","caseNumber","caseStyle","caseKey","roles"]},"ContactUsageBillingEntityDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string","nullable":true}},"required":["id","name"]},"ContactUsageOtherDto":{"type":"object","properties":{"participants":{"type":"number","description":"Case participant rows (plaintiffs, defendants, witnesses, ...)."},"victims":{"type":"number"},"officers":{"type":"number","description":"Arresting / police officer rows."},"prosecutors":{"type":"number"},"bondsmen":{"type":"number"},"rollCallLocations":{"type":"number"},"liens":{"type":"number"},"doctors":{"type":"number"},"providers":{"type":"number"},"insurances":{"type":"number","description":"Organizations only; always 0 for a person."},"subrogors":{"type":"number","description":"Organizations only; always 0 for a person."},"workHistories":{"type":"number","description":"Organizations only (employer); always 0 for a person."}},"required":["participants","victims","officers","prosecutors","bondsmen","rollCallLocations","liens","doctors","providers","insurances","subrogors","workHistories"]},"ContactUsageDto":{"type":"object","properties":{"inUse":{"type":"boolean","description":"True when any link blocks deletion."},"caseCount":{"type":"number","description":"Distinct live cases the contact is linked to."},"cases":{"description":"Up to 25 of those cases, ordered by case number.","type":"array","items":{"$ref":"#/components/schemas/ContactUsageCaseDto"}},"billingEntityCount":{"type":"number"},"billingEntities":{"description":"Up to 25 linked billing entities, ordered by name.","type":"array","items":{"$ref":"#/components/schemas/ContactUsageBillingEntityDto"}},"other":{"$ref":"#/components/schemas/ContactUsageOtherDto"}},"required":["inUse","caseCount","cases","billingEntityCount","billingEntities","other"]},"UpdateContactDto":{"type":"object","properties":{"email":{"type":"string","nullable":true,"description":"Send null to clear it."},"notes":{"type":"string","nullable":true,"description":"Send null to clear it."},"phones":{"type":"array","items":{"$ref":"#/components/schemas/CreatePhoneDto"}},"addresses":{"type":"array","items":{"$ref":"#/components/schemas/CreateAddressDto"}}}},"UpdatePersonDto":{"type":"object","properties":{"middleName":{"type":"string","nullable":true,"description":"Null clears it on update."},"genderId":{"type":"number","nullable":true,"description":"Gender lookup id (GET /lookups/genders). Null clears it on update."},"dateOfBirth":{"type":"string","nullable":true,"description":"Date of birth (ISO 8601 date). Null clears it on update."},"driversLicenseStateId":{"type":"number","nullable":true,"description":"Issuing state of the drivers license (GET /lookups/states). Null clears it on update."},"yearsSchooling":{"type":"number","nullable":true,"description":"Years of high school completed. Null clears it on update."},"highSchoolGrad":{"type":"boolean","nullable":true,"description":"Null clears it on update."},"highSchoolName":{"type":"string","nullable":true,"description":"Null clears it on update."},"yearsCollege":{"type":"number","nullable":true,"description":"Years of college completed. Null clears it on update."},"collegeGrad":{"type":"boolean","nullable":true,"description":"Null clears it on update."},"collegeName":{"type":"string","nullable":true,"description":"Null clears it on update."},"gradePointAvg":{"type":"string","nullable":true,"description":"Grade point average (decimal string, e.g. \"3.50\"). Null clears it on update."},"firstName":{"type":"string"},"lastName":{"type":"string"},"ssn":{"type":"string"},"driversLicense":{"type":"string"},"personTypeId":{"type":"number"},"contact":{"$ref":"#/components/schemas/UpdateContactDto"}}},"ContactInUseErrorDto":{"type":"object","properties":{"statusCode":{"type":"number","example":409},"code":{"type":"string","example":"CONTACT_IN_USE"},"message":{"type":"string","example":"This person is linked to 2 cases. Remove them from those cases first."},"usage":{"$ref":"#/components/schemas/ContactUsageDto"}},"required":["statusCode","code","message","usage"]},"OrganizationDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"organizationTypeId":{"type":"object","nullable":true},"contact":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/ContactDto"}]},"creationTime":{"format":"date-time","type":"string"}},"required":["id","name","organizationTypeId","contact","creationTime"]},"OrganizationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateOrganizationDto":{"type":"object","properties":{"name":{"type":"string"},"organizationTypeId":{"type":"number"},"contact":{"$ref":"#/components/schemas/CreateContactDto"}},"required":["name"]},"UpdateOrganizationDto":{"type":"object","properties":{"name":{"type":"string"},"organizationTypeId":{"type":"number","nullable":true,"description":"Organization type lookup id (GET /lookups/organization-types). Send null to clear it."},"contact":{"$ref":"#/components/schemas/UpdateContactDto"}}},"LinkedPersonDto":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"contact":{"nullable":true,"description":"Contact details. Null when the caller lacks People.View.","type":"object","allOf":[{"$ref":"#/components/schemas/ContactDto"}]},"dateOfBirth":{"type":"string","nullable":true,"description":"Date of birth (YYYY-MM-DD). Personal detail like the contact: null without People.View."}},"required":["id","firstName","lastName","contact"]},"LinkedOrganizationDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"contact":{"nullable":true,"description":"Contact details. Null when the caller lacks People.View.","type":"object","allOf":[{"$ref":"#/components/schemas/ContactDto"}]}},"required":["id","name","contact"]},"ParticipantDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"participantType":{"type":"string","enum":["PLAINTIFF","DEFENDANT","ADJUSTER","OPPOSING_COUNSEL","CASE_MANAGER","JUDGE","PHYSICAL_THERAPIST","REHAB_COUNSELOR","WITNESS","RELATIVE"]},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"relationshipId":{"type":"object","nullable":true},"personRoleId":{"type":"object","nullable":true},"isPrimary":{"type":"boolean"},"statement":{"type":"object","nullable":true},"statementDate":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"personFirstName":{"type":"object","nullable":true},"personLastName":{"type":"object","nullable":true},"personEmail":{"type":"object","nullable":true},"personPhone":{"type":"object","nullable":true},"organizationName":{"type":"object","nullable":true},"person":{"nullable":true,"description":"The linked person. Null when none is linked or the linked person was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedPersonDto"}]},"organization":{"nullable":true,"description":"The linked organization. Null when none is linked or the linked organization was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedOrganizationDto"}]}},"required":["id","caseId","participantType","personId","organizationId","relationshipId","personRoleId","isPrimary","statement","statementDate","notes","creationTime","personFirstName","personLastName","personEmail","personPhone","organizationName","person","organization"]},"ParticipantListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ParticipantDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateParticipantDto":{"type":"object","properties":{"participantType":{"type":"string","enum":["PLAINTIFF","DEFENDANT","ADJUSTER","OPPOSING_COUNSEL","CASE_MANAGER","JUDGE","PHYSICAL_THERAPIST","REHAB_COUNSELOR","WITNESS","RELATIVE"]},"personId":{"type":"string","description":"Person id (bigint as string). Mutually exclusive with organizationId."},"organizationId":{"type":"number","description":"Organization id. Mutually exclusive with personId."},"relationshipId":{"type":"number","description":"Relationship to plaintiff (when participantType = RELATIVE)."},"personRoleId":{"type":"number","description":"Person role the participant fills (e.g. Presiding Judge)."},"isPrimary":{"type":"boolean","default":false},"statement":{"type":"string","description":"Witness statement (participantType = WITNESS)."},"statementDate":{"type":"string","description":"Witness statement date (ISO)."},"notes":{"type":"string"}},"required":["participantType"]},"CreatePlaintiffDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id (bigint as string)."},"isPrimary":{"type":"boolean","default":false},"notes":{"type":"string"}}},"UpdateParticipantDto":{"type":"object","properties":{"participantType":{"type":"string","enum":["PLAINTIFF","DEFENDANT","ADJUSTER","OPPOSING_COUNSEL","CASE_MANAGER","JUDGE","PHYSICAL_THERAPIST","REHAB_COUNSELOR","WITNESS","RELATIVE"]},"personId":{"type":"string"},"organizationId":{"type":"number"},"relationshipId":{"type":"number"},"personRoleId":{"type":"number","description":"Person role the participant fills (e.g. Presiding Judge)."},"isPrimary":{"type":"boolean"},"statement":{"type":"string","description":"Witness statement (participantType = WITNESS)."},"statementDate":{"type":"string","description":"Witness statement date (ISO)."},"notes":{"type":"string"}}},"CaseDetailFieldTypeDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"CaseDetailFieldDto":{"type":"object","properties":{"id":{"type":"number"},"detailClassId":{"type":"number"},"fieldTypeId":{"type":"number"},"name":{"type":"string"},"label":{"type":"object","nullable":true},"isRequired":{"type":"boolean"},"isVisibleToClient":{"type":"boolean"},"sortOrder":{"type":"number"}},"required":["id","detailClassId","fieldTypeId","name","label","isRequired","isVisibleToClient","sortOrder"]},"CaseDetailClassDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"label":{"type":"object","nullable":true},"caseTypeId":{"type":"object","nullable":true},"sortOrder":{"type":"number"},"fields":{"type":"array","items":{"$ref":"#/components/schemas/CaseDetailFieldDto"}}},"required":["id","name","label","caseTypeId","sortOrder","fields"]},"CreateCaseDetailClassDto":{"type":"object","properties":{"name":{"type":"string","description":"System name (legacy ClassName)."},"label":{"type":"string","description":"Display label; defaults to the name."},"caseTypeId":{"type":"number","description":"Scope the class to a case type."},"sortOrder":{"type":"number","default":0}},"required":["name"]},"UpdateCaseDetailClassDto":{"type":"object","properties":{"name":{"type":"string"},"label":{"type":"string"},"caseTypeId":{"type":"number"},"sortOrder":{"type":"number"}}},"CreateCaseDetailFieldDto":{"type":"object","properties":{"detailClassId":{"type":"number"},"fieldTypeId":{"type":"number"},"name":{"type":"string","description":"System name (legacy FieldName)."},"label":{"type":"string","description":"Display label; defaults to the name."},"isRequired":{"type":"boolean","default":false},"isVisibleToClient":{"type":"boolean","description":"Expose this field on the client portal.","default":false},"sortOrder":{"type":"number","default":0}},"required":["detailClassId","fieldTypeId","name"]},"UpdateCaseDetailFieldDto":{"type":"object","properties":{"detailClassId":{"type":"number"},"fieldTypeId":{"type":"number"},"name":{"type":"string"},"label":{"type":"string"},"isRequired":{"type":"boolean"},"isVisibleToClient":{"type":"boolean"},"sortOrder":{"type":"number"}}},"CaseDetailValueDto":{"type":"object","properties":{"fieldId":{"type":"number"},"value":{"type":"object","nullable":true}},"required":["fieldId","value"]},"SetCaseDetailValueDto":{"type":"object","properties":{"fieldId":{"type":"number"},"value":{"type":"object","nullable":true}},"required":["fieldId"]},"SetCaseDetailValuesDto":{"type":"object","properties":{"values":{"type":"array","items":{"$ref":"#/components/schemas/SetCaseDetailValueDto"}}},"required":["values"]},"DocumentCategoryDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"CreateDocumentCategoryDto":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]},"DocumentDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"documentCategoryId":{"type":"object","nullable":true},"documentCategoryName":{"type":"object","nullable":true,"description":"Resolved category name."},"fileName":{"type":"string"},"description":{"type":"object","nullable":true},"contentType":{"type":"object","nullable":true},"sizeBytes":{"type":"object","nullable":true},"sharepointDriveId":{"type":"object","nullable":true},"sharepointItemId":{"type":"object","nullable":true},"sharepointWebUrl":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"lastModificationTime":{"type":"object","nullable":true,"description":"Row audit last-modification timestamp."},"lastModifiedByName":{"type":"object","nullable":true,"description":"Resolved name of the user who last modified the row."}},"required":["id","caseId","documentCategoryId","documentCategoryName","fileName","description","contentType","sizeBytes","sharepointDriveId","sharepointItemId","sharepointWebUrl","creationTime","lastModificationTime","lastModifiedByName"]},"DocumentListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DocumentDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"BreadcrumbDto":{"type":"object","properties":{"name":{"type":"string"},"path":{"type":"string","description":"Path to pass back as ?path= to navigate here."}},"required":["name","path"]},"DriveItemDto":{"type":"object","properties":{"id":{"type":"string","description":"Graph drive-item id."},"name":{"type":"string"},"isFolder":{"type":"boolean","description":"True for folders, which can be navigated into."},"path":{"type":"string","description":"Path relative to the case folder, for navigation."},"webUrl":{"type":"object","nullable":true,"description":"Browser URL to open the item in SharePoint."},"sizeBytes":{"type":"object","nullable":true},"contentType":{"type":"object","nullable":true},"lastModifiedAt":{"type":"object","nullable":true},"lastModifiedBy":{"type":"string","nullable":true,"description":"Display name from SharePoint/Egnyte, not CaseWizard."}},"required":["id","name","isFolder","path","webUrl","sizeBytes","contentType","lastModifiedAt","lastModifiedBy"]},"DriveListingDto":{"type":"object","properties":{"driveId":{"type":"string","description":"Graph drive id for items in this listing (needed for ad-hoc document merge)."},"rootSegments":{"description":"Fixed folder segments above the browse root, e.g. [\"CaseWizard\",\"12\"]. Display-only context so the breadcrumb shows where in the library the user actually is; the client cannot navigate above the last of these, which IS the browse root.","type":"array","items":{"type":"string"}},"breadcrumb":{"description":"Segments from the browse root to the current folder.","type":"array","items":{"$ref":"#/components/schemas/BreadcrumbDto"}},"items":{"type":"array","items":{"$ref":"#/components/schemas/DriveItemDto"}},"currentWebUrl":{"type":"string","nullable":true,"description":"Browser URL of the current folder in SharePoint."},"rootWebUrl":{"type":"string","nullable":true,"description":"Browser URL of the listing root in SharePoint."}},"required":["driveId","rootSegments","breadcrumb","items","currentWebUrl","rootWebUrl"]},"RegisterDocumentDto":{"type":"object","properties":{"fileName":{"type":"string"},"documentCategoryId":{"type":"number"},"description":{"type":"string"},"contentType":{"type":"string"},"sizeBytes":{"type":"string","description":"Size in bytes (as string for large values)."},"sharepointDriveId":{"type":"string","description":"Microsoft Graph drive id."},"sharepointItemId":{"type":"string","description":"Microsoft Graph item id."},"sharepointWebUrl":{"type":"string","description":"SharePoint web URL for the item."}},"required":["fileName"]},"DocumentDownloadDto":{"type":"object","properties":{"url":{"type":"string","description":"URL to view/download the document (SharePoint web URL)."}},"required":["url"]},"UpdateDocumentDto":{"type":"object","properties":{"fileName":{"type":"string"},"documentCategoryId":{"type":"number"},"description":{"type":"string"}}},"DocumentStorageSettingsDto":{"type":"object","properties":{"activeProvider":{"type":"string","enum":["none","sharepoint","egnyte"],"description":"Firm-wide active document storage provider."},"sharepointEnabled":{"type":"boolean","description":"Whether SharePoint document storage is enabled."},"egnyteEnabled":{"type":"boolean","description":"Whether Egnyte document storage is enabled."}},"required":["activeProvider","sharepointEnabled","egnyteEnabled"]},"UpdateDocumentStorageSettingsDto":{"type":"object","properties":{"activeProvider":{"type":"string","enum":["none","sharepoint","egnyte"],"description":"Switch the firm to exactly one document storage provider."}},"required":["activeProvider"]},"SharepointSettingsDto":{"type":"object","properties":{"isEnabled":{"type":"boolean","description":"Whether SharePoint document features are on for this firm."},"siteUrl":{"type":"object","description":"Site URL as entered, e.g. https://yourfirm.sharepoint.com/sites/CaseFiles"},"siteResolved":{"type":"boolean","description":"Whether the site URL has been resolved to stable Graph ids. False means the site was saved but could not be reached, so documents will not work yet."},"libraryWebUrl":{"type":"object","description":"Browser URL of the document library root."},"rootFolder":{"type":"string","description":"Folder under the library root holding per-case folders."},"templateFolder":{"type":"object","description":"Library-relative folder holding mail-merge templates."},"entraTenantId":{"type":"object","description":"Microsoft tenant (tid) this firm is linked to."},"adminConsentAt":{"type":"object","description":"When the firm was linked to its Microsoft tenant."}},"required":["isEnabled"]},"UpdateSharepointSettingsDto":{"type":"object","properties":{"isEnabled":{"type":"boolean","description":"Turn SharePoint document features on or off."},"siteUrl":{"type":"string","description":"Full SharePoint site URL. On save this is resolved to stable site and drive ids using the caller's own Microsoft account, so an unreachable site fails here rather than later.","example":"https://yourfirm.sharepoint.com/sites/CaseFiles"},"templateFolder":{"type":"string","description":"Library-relative folder holding mail-merge templates, e.g. Templates."}}},"AdminConsentUrlDto":{"type":"object","properties":{"adminConsentUrl":{"type":"string","description":"URL for a Microsoft Global Admin to approve CaseWizard for the firm. Required because the delegated Sites.ReadWrite.All scope cannot be consented by individual users."}},"required":["adminConsentUrl"]},"CompleteAdminConsentDto":{"type":"object","properties":{"tenant":{"type":"string","description":"The `tenant` query parameter Microsoft appends to the redirect after admin consent. This is the firm's Entra tenant id (tid) and is what links the firm to its organisation."},"state":{"type":"string","description":"The opaque `state` issued by admin-consent-url and echoed back by Microsoft."}},"required":["tenant","state"]},"EgnyteSettingsDto":{"type":"object","properties":{"isEnabled":{"type":"boolean","description":"Whether Egnyte document features are on for this firm."},"domain":{"type":"object","description":"Egnyte subdomain only, e.g. acme for acme.egnyte.com."},"domainResolved":{"type":"boolean","description":"Whether the domain has been verified with an admin delegated token."},"domainWebUrl":{"type":"object","description":"Browser URL of the Egnyte domain root."},"rootFolder":{"type":"string","description":"Folder under the domain holding per-case folders."},"templateFolder":{"type":"object","description":"Folder holding mail-merge templates."}},"required":["isEnabled"]},"UpdateEgnyteSettingsDto":{"type":"object","properties":{"isEnabled":{"type":"boolean","description":"Turn Egnyte document features on or off."},"domain":{"type":"string","description":"Egnyte subdomain or full URL. Resolved to subdomain on save.","example":"acme"},"templateFolder":{"type":"string","description":"Folder holding mail-merge templates."},"rootFolder":{"type":"string","description":"Folder under the domain holding per-case folders.","example":"Shared/CaseWizard"}}},"EventTypeDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"color":{"type":"object","nullable":true}},"required":["id","name","color"]},"CreateEventTypeDto":{"type":"object","properties":{"name":{"type":"string"},"color":{"type":"string"}},"required":["name"]},"EventDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"object","nullable":true},"caseKey":{"type":"number","nullable":true,"description":"The case number shown in case URLs (Case.caseKey)."},"caseLabel":{"type":"object","nullable":true,"description":"Resolved case label (caseStyle, fallback caseNumber)."},"eventTypeId":{"type":"object","nullable":true},"eventTypeName":{"type":"object","nullable":true,"description":"Resolved event-type name."},"title":{"type":"string"},"description":{"type":"object","nullable":true},"location":{"type":"object","nullable":true},"startTime":{"format":"date-time","type":"string"},"endTime":{"type":"object","nullable":true},"isAllDay":{"type":"boolean"},"reminder":{"type":"object","nullable":true},"reminderDate":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"lastModificationTime":{"type":"object","nullable":true}},"required":["id","caseId","caseKey","caseLabel","eventTypeId","eventTypeName","title","description","location","startTime","endTime","isAllDay","reminder","reminderDate","creationTime","lastModificationTime"]},"EventListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/EventDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateEventDto":{"type":"object","properties":{"title":{"type":"string"},"caseId":{"type":"number"},"eventTypeId":{"type":"number"},"description":{"type":"string"},"location":{"type":"string"},"startTime":{"type":"string","description":"ISO 8601 start timestamp."},"endTime":{"type":"string","description":"ISO 8601 end timestamp."},"isAllDay":{"type":"boolean","default":false},"reminder":{"type":"boolean","description":"Whether a follow-up reminder is set."},"reminderDate":{"type":"string","description":"ISO 8601 reminder timestamp."}},"required":["title","eventTypeId","startTime"]},"UpdateEventDto":{"type":"object","properties":{"title":{"type":"string"},"eventTypeId":{"type":"number"},"description":{"type":"string","nullable":true,"description":"Send null to clear it."},"location":{"type":"string","nullable":true,"description":"Send null to clear it."},"startTime":{"type":"string"},"endTime":{"type":"string"},"isAllDay":{"type":"boolean"},"reminder":{"type":"boolean"},"reminderDate":{"type":"string","nullable":true,"description":"ISO 8601 reminder timestamp. Send null to clear it."}}},"CalendarSubscriptionDto":{"type":"object","properties":{"token":{"type":"string","description":"Opaque feed token embedded in the public ICS URL path."},"feedPath":{"type":"string","description":"Path under /v1 for the public ICS feed (e.g. /calendar/feeds/{token}.ics).","example":"/calendar/feeds/abc.ics"}},"required":["token","feedPath"]},"InjuryDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"injuryTypeId":{"type":"object","nullable":true},"bodyPart":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"injuryDate":{"type":"object","nullable":true},"icdCode":{"type":"object","nullable":true},"longDescription":{"type":"object","nullable":true},"county":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","injuryTypeId","bodyPart","description","injuryDate","icdCode","longDescription","county","notes","creationTime"]},"InjuryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/InjuryDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateInjuryDto":{"type":"object","properties":{"injuryTypeId":{"type":"number"},"bodyPart":{"type":"string"},"description":{"type":"string"},"injuryDate":{"type":"string","description":"ISO date string. Always client-supplied, never defaulted."},"icdCode":{"type":"string"},"longDescription":{"type":"string"},"county":{"type":"string"},"notes":{"type":"string"}}},"UpdateInjuryDto":{"type":"object","properties":{"injuryTypeId":{"type":"number"},"bodyPart":{"type":"string"},"description":{"type":"string"},"injuryDate":{"type":"string","description":"ISO date string. Always client-supplied, never defaulted."},"icdCode":{"type":"string"},"longDescription":{"type":"string"},"county":{"type":"string"},"notes":{"type":"string"}}},"DoctorDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"doctorSpecialtyId":{"type":"object","nullable":true},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"specialtyName":{"type":"object","nullable":true},"personFirstName":{"type":"object","nullable":true},"personLastName":{"type":"object","nullable":true},"personEmail":{"type":"object","nullable":true},"personPhone":{"type":"object","nullable":true},"organizationName":{"type":"object","nullable":true}},"required":["id","plaintiffParticipantId","doctorSpecialtyId","personId","organizationId","notes","creationTime","specialtyName","personFirstName","personLastName","personEmail","personPhone","organizationName"]},"DoctorListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/DoctorDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateDoctorDto":{"type":"object","properties":{"doctorSpecialtyId":{"type":"number"},"personId":{"type":"string","description":"Person id (bigint as string)."},"organizationId":{"type":"number"},"notes":{"type":"string"}}},"UpdateDoctorDto":{"type":"object","properties":{"doctorSpecialtyId":{"type":"number"},"personId":{"type":"string"},"organizationId":{"type":"number"},"notes":{"type":"string"}}},"ProviderDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"object","nullable":true},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"name":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","personId","organizationId","name","notes","creationTime"]},"ProviderListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ProviderDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateProviderDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id (bigint as string)."},"organizationId":{"type":"number"},"name":{"type":"string"},"notes":{"type":"string"}}},"UpdateProviderDto":{"type":"object","properties":{"personId":{"type":"string"},"organizationId":{"type":"number"},"name":{"type":"string"},"notes":{"type":"string"}}},"MedicationDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"medicationIndexId":{"type":"object","nullable":true},"name":{"type":"object","nullable":true},"dosage":{"type":"object","nullable":true},"frequency":{"type":"object","nullable":true},"dateLastTaken":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","medicationIndexId","name","dosage","frequency","dateLastTaken","notes","creationTime"]},"MedicationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MedicationDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateMedicationDto":{"type":"object","properties":{"medicationIndexId":{"type":"number"},"name":{"type":"string"},"dosage":{"type":"string"},"frequency":{"type":"string"},"dateLastTaken":{"type":"string","description":"ISO date the medication was last taken."},"notes":{"type":"string"}}},"UpdateMedicationDto":{"type":"object","properties":{"medicationIndexId":{"type":"number"},"name":{"type":"string"},"dosage":{"type":"string"},"frequency":{"type":"string"},"dateLastTaken":{"type":"string","description":"ISO date the medication was last taken."},"notes":{"type":"string"}}},"InsuranceDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"insuranceTypeId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"carrierName":{"type":"object","nullable":true},"policyNumber":{"type":"object","nullable":true},"groupNumber":{"type":"object","nullable":true},"limits":{"type":"object","nullable":true},"claimNumber":{"type":"object","nullable":true},"fileNumber":{"type":"object","nullable":true},"agent":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","insuranceTypeId","organizationId","carrierName","policyNumber","groupNumber","limits","claimNumber","fileNumber","agent","notes","creationTime"]},"InsuranceListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/InsuranceDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateInsuranceDto":{"type":"object","properties":{"insuranceTypeId":{"type":"number"},"organizationId":{"type":"number"},"carrierName":{"type":"string"},"policyNumber":{"type":"string"},"groupNumber":{"type":"string"},"limits":{"type":"string"},"claimNumber":{"type":"string"},"fileNumber":{"type":"string"},"agent":{"type":"string"},"notes":{"type":"string"}}},"UpdateInsuranceDto":{"type":"object","properties":{"insuranceTypeId":{"type":"number"},"organizationId":{"type":"number"},"carrierName":{"type":"string"},"policyNumber":{"type":"string"},"groupNumber":{"type":"string"},"limits":{"type":"string"},"claimNumber":{"type":"string"},"fileNumber":{"type":"string"},"agent":{"type":"string"},"notes":{"type":"string"}}},"SubrogorDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"organizationId":{"type":"object","nullable":true},"organizationName":{"type":"object","nullable":true},"name":{"type":"object","nullable":true},"firstName":{"type":"object","nullable":true},"lastName":{"type":"object","nullable":true},"email":{"type":"object","nullable":true},"phone":{"type":"object","nullable":true},"amount":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","organizationId","organizationName","name","firstName","lastName","email","phone","amount","notes","creationTime"]},"SubrogorListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SubrogorDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateSubrogorDto":{"type":"object","properties":{"organizationId":{"type":"number"},"name":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"amount":{"type":"string","description":"Decimal amount as string."},"notes":{"type":"string"}}},"UpdateSubrogorDto":{"type":"object","properties":{"organizationId":{"type":"number"},"name":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"amount":{"type":"string","description":"Decimal amount as string."},"notes":{"type":"string"}}},"PriorClaimDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"description":{"type":"object","nullable":true},"claimDate":{"type":"object","nullable":true},"amount":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","description","claimDate","amount","notes","creationTime"]},"PriorClaimListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PriorClaimDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreatePriorClaimDto":{"type":"object","properties":{"description":{"type":"string"},"claimDate":{"type":"string","description":"ISO date string."},"amount":{"type":"string","description":"Decimal amount as string."},"notes":{"type":"string"}}},"UpdatePriorClaimDto":{"type":"object","properties":{"description":{"type":"string"},"claimDate":{"type":"string","description":"ISO date string."},"amount":{"type":"string","description":"Decimal amount as string."},"notes":{"type":"string"}}},"WorkHistoryDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"organizationId":{"type":"object","nullable":true},"employerName":{"type":"object","nullable":true},"jobTitle":{"type":"object","nullable":true},"startDate":{"type":"object","nullable":true},"endDate":{"type":"object","nullable":true},"supervisorFirstName":{"type":"object","nullable":true},"supervisorLastName":{"type":"object","nullable":true},"supervisorPhone":{"type":"object","nullable":true},"supervisorEmail":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","organizationId","employerName","jobTitle","startDate","endDate","supervisorFirstName","supervisorLastName","supervisorPhone","supervisorEmail","notes","creationTime"]},"WorkHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/WorkHistoryDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateWorkHistoryDto":{"type":"object","properties":{"organizationId":{"type":"number"},"employerName":{"type":"string"},"jobTitle":{"type":"string"},"startDate":{"type":"string","description":"ISO date string."},"endDate":{"type":"string","description":"ISO date string."},"supervisorFirstName":{"type":"string"},"supervisorLastName":{"type":"string"},"supervisorPhone":{"type":"string"},"supervisorEmail":{"type":"string"},"notes":{"type":"string"}}},"UpdateWorkHistoryDto":{"type":"object","properties":{"organizationId":{"type":"number"},"employerName":{"type":"string"},"jobTitle":{"type":"string"},"startDate":{"type":"string","description":"ISO date string."},"endDate":{"type":"string","description":"ISO date string."},"supervisorFirstName":{"type":"string"},"supervisorLastName":{"type":"string"},"supervisorPhone":{"type":"string"},"supervisorEmail":{"type":"string"},"notes":{"type":"string"}}},"MedicalExpenseDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"providerId":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"amount":{"type":"object","nullable":true},"expenseDate":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","providerId","description","amount","expenseDate","notes","creationTime"]},"MedicalExpenseListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/MedicalExpenseDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateMedicalExpenseDto":{"type":"object","properties":{"providerId":{"type":"number"},"description":{"type":"string"},"amount":{"type":"string","description":"Decimal amount as string."},"expenseDate":{"type":"string","description":"ISO date string."},"notes":{"type":"string"}}},"UpdateMedicalExpenseDto":{"type":"object","properties":{"providerId":{"type":"number","nullable":true,"description":"Send null to clear it."},"description":{"type":"string","nullable":true,"description":"Send null to clear it."},"amount":{"type":"string","nullable":true,"description":"Decimal amount as string. Send null to clear it."},"expenseDate":{"type":"string","nullable":true,"description":"ISO date string. Send null to clear it."},"notes":{"type":"string","nullable":true,"description":"Send null to clear it."}}},"PatientHistoryDto":{"type":"object","properties":{"id":{"type":"number"},"plaintiffParticipantId":{"type":"number"},"note":{"type":"string"},"historyDate":{"type":"object","nullable":true},"doctorId":{"type":"object","nullable":true},"doctorSpecialtyName":{"type":"object","nullable":true},"doctorPersonFirstName":{"type":"object","nullable":true},"doctorPersonLastName":{"type":"object","nullable":true},"doctorOrganizationName":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","plaintiffParticipantId","note","historyDate","doctorId","doctorSpecialtyName","doctorPersonFirstName","doctorPersonLastName","doctorOrganizationName","creationTime"]},"PatientHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PatientHistoryDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreatePatientHistoryDto":{"type":"object","properties":{"note":{"type":"string"},"doctorId":{"type":"number","description":"One of the plaintiff's doctors."},"historyDate":{"type":"string","description":"ISO date string."}},"required":["note"]},"UpdatePatientHistoryDto":{"type":"object","properties":{"note":{"type":"string"},"doctorId":{"type":"number","description":"One of the plaintiff's doctors."},"historyDate":{"type":"string","description":"ISO date string."}}},"LienDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"lienTypeId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"personId":{"type":"object","nullable":true},"lienDate":{"type":"object","nullable":true},"fileDate":{"type":"object","nullable":true},"lienTypeName":{"type":"object","nullable":true},"organizationName":{"type":"object","nullable":true},"personName":{"type":"object","nullable":true},"amount":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"status":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","caseId","lienTypeId","organizationId","personId","lienDate","fileDate","lienTypeName","organizationName","personName","amount","description","status","creationTime"]},"LienListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LienDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateLienDto":{"type":"object","properties":{"lienTypeId":{"type":"number","nullable":true,"description":"Null clears it on update."},"organizationId":{"type":"number","nullable":true,"description":"Null clears it on update."},"personId":{"type":"string","nullable":true,"description":"Person the lien belongs to (people id as string). Null clears it on update."},"lienDate":{"type":"string","nullable":true,"description":"ISO date string. Always client-supplied, never defaulted. Null clears it on update."},"fileDate":{"type":"string","nullable":true,"description":"ISO date string. Null clears it on update."},"amount":{"type":"string","nullable":true,"description":"Decimal amount as a string. Null clears it on update."},"description":{"type":"string","nullable":true,"description":"Null clears it on update."},"status":{"type":"string"}}},"UpdateLienDto":{"type":"object","properties":{"lienTypeId":{"type":"number","nullable":true,"description":"Null clears it on update."},"organizationId":{"type":"number","nullable":true,"description":"Null clears it on update."},"personId":{"type":"string","nullable":true,"description":"Person the lien belongs to (people id as string). Null clears it on update."},"lienDate":{"type":"string","nullable":true,"description":"ISO date string. Always client-supplied, never defaulted. Null clears it on update."},"fileDate":{"type":"string","nullable":true,"description":"ISO date string. Null clears it on update."},"amount":{"type":"string","nullable":true,"description":"Decimal amount as a string. Null clears it on update."},"description":{"type":"string","nullable":true,"description":"Null clears it on update."},"status":{"type":"string"}}},"SettlementDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"settlementType":{"type":"object","nullable":true},"offerTypeId":{"type":"object","nullable":true},"offerTypeName":{"type":"object","nullable":true},"madeBy":{"type":"string","enum":["US","THEM"],"nullable":true},"openMedical":{"type":"object","nullable":true},"monthsMedical":{"type":"object","nullable":true},"amount":{"type":"object","nullable":true},"settlementDate":{"type":"object","nullable":true},"status":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","caseId","settlementType","offerTypeId","offerTypeName","madeBy","openMedical","monthsMedical","amount","settlementDate","status","notes","creationTime"]},"SettlementListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SettlementDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateSettlementDto":{"type":"object","properties":{"settlementType":{"type":"string","description":"Free-text settlement type / stage. @deprecated Use offerTypeId instead."},"offerTypeId":{"type":"number","nullable":true,"description":"Offer type (offer_types lookup: Lump sum, Structured). Null clears it on update."},"madeBy":{"type":"string","enum":["US","THEM"],"nullable":true,"description":"Which side made the offer. Null clears it on update."},"openMedical":{"type":"string","nullable":true,"description":"Open medical terms (free text). Null clears it on update."},"monthsMedical":{"type":"number","nullable":true,"description":"Months of medical coverage. Null clears it on update."},"amount":{"type":"string","nullable":true,"description":"Decimal amount as a string. Null clears it on update."},"settlementDate":{"type":"string","nullable":true,"description":"Settlement date (ISO). Null clears it on update."},"status":{"type":"string"},"notes":{"type":"string","nullable":true,"description":"Null clears it on update."}}},"UpdateSettlementDto":{"type":"object","properties":{"settlementType":{"type":"string","description":"Free-text settlement type / stage. @deprecated Use offerTypeId instead."},"offerTypeId":{"type":"number","nullable":true,"description":"Offer type (offer_types lookup: Lump sum, Structured). Null clears it on update."},"madeBy":{"type":"string","enum":["US","THEM"],"nullable":true,"description":"Which side made the offer. Null clears it on update."},"openMedical":{"type":"string","nullable":true,"description":"Open medical terms (free text). Null clears it on update."},"monthsMedical":{"type":"number","nullable":true,"description":"Months of medical coverage. Null clears it on update."},"amount":{"type":"string","nullable":true,"description":"Decimal amount as a string. Null clears it on update."},"settlementDate":{"type":"string","nullable":true,"description":"Settlement date (ISO). Null clears it on update."},"status":{"type":"string"},"notes":{"type":"string","nullable":true,"description":"Null clears it on update."}}},"CriminalChargeIndexDto":{"type":"object","properties":{"id":{"type":"number"},"charge":{"type":"string"},"penalty":{"type":"string","nullable":true},"statuteSection":{"type":"string","nullable":true}},"required":["id","charge","penalty","statuteSection"]},"CriminalChargeDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"criminalChargeIndexId":{"type":"number","nullable":true},"index":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/CriminalChargeIndexDto"}]},"chargeDate":{"format":"date-time","type":"string","nullable":true},"counts":{"type":"number","nullable":true},"description":{"type":"string","nullable":true,"description":"API-only extra."},"disposition":{"type":"string","nullable":true,"description":"API-only extra."},"notes":{"type":"string","nullable":true,"description":"API-only extra."},"creationTime":{"format":"date-time","type":"string"}},"required":["id","caseId","criminalChargeIndexId","index","chargeDate","counts","description","disposition","notes","creationTime"]},"CriminalChargeListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CriminalChargeDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"NewCriminalChargeIndexDto":{"type":"object","properties":{"charge":{"type":"string","maxLength":256},"penalty":{"type":"string","maxLength":256},"statuteSection":{"type":"string","maxLength":256}},"required":["charge"]},"CreateCriminalChargeDto":{"type":"object","properties":{"criminalChargeIndexId":{"type":"number","description":"An existing row of the tenant's charge index. Mutually exclusive with newIndex."},"newIndex":{"description":"Create a new charge-index row and link it (legacy CriminalChargeAppService.CreateNewCharge). Mutually exclusive with criminalChargeIndexId.","allOf":[{"$ref":"#/components/schemas/NewCriminalChargeIndexDto"}]},"chargeDate":{"type":"string","description":"Charge date, ISO date string (legacy CriminalChargeDate)."},"counts":{"type":"number","description":"Number of counts (legacy Counts).","minimum":0},"description":{"type":"string","description":"API-only extra with no legacy equivalent."},"disposition":{"type":"string","description":"API-only extra with no legacy equivalent."},"notes":{"type":"string","description":"API-only extra with no legacy equivalent."}}},"UpdateCriminalChargeDto":{"type":"object","properties":{"criminalChargeIndexId":{"type":"number","description":"An existing row of the tenant's charge index. Mutually exclusive with newIndex."},"newIndex":{"description":"Create a new charge-index row and link it (legacy CriminalChargeAppService.CreateNewCharge). Mutually exclusive with criminalChargeIndexId.","allOf":[{"$ref":"#/components/schemas/NewCriminalChargeIndexDto"}]},"chargeDate":{"type":"string","description":"Charge date, ISO date string (legacy CriminalChargeDate)."},"counts":{"type":"number","description":"Number of counts (legacy Counts).","minimum":0},"description":{"type":"string","description":"API-only extra with no legacy equivalent."},"disposition":{"type":"string","description":"API-only extra with no legacy equivalent."},"notes":{"type":"string","description":"API-only extra with no legacy equivalent."},"penalty":{"type":"string","maxLength":256,"description":"With criminalChargeIndexId (or the current index), updates that index row penalty, as legacy UpdateCriminalCharge did."},"statuteSection":{"type":"string","maxLength":256,"description":"With criminalChargeIndexId (or the current index), updates that index row statute section, as legacy UpdateCriminalCharge did."}}},"VictimDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"personId":{"type":"object","nullable":true},"organizationId":{"type":"number","nullable":true},"name":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"person":{"nullable":true,"description":"The linked person. Null when none is linked or the linked person was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedPersonDto"}]},"organization":{"nullable":true,"description":"The linked organization. Null when none is linked or the linked organization was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedOrganizationDto"}]}},"required":["id","caseId","personId","organizationId","name","notes","creationTime","person","organization"]},"VictimListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/VictimDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateVictimDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number","description":"Organization victim (legacy Victim.OrganizationId)."},"name":{"type":"string"},"notes":{"type":"string"}}},"UpdateVictimDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number","description":"Organization victim (legacy Victim.OrganizationId)."},"name":{"type":"string"},"notes":{"type":"string"}}},"PoliceOfficerDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"badgeNumber":{"type":"object","nullable":true},"supervisor":{"type":"string","nullable":true},"name":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"person":{"nullable":true,"description":"The linked person. Null when none is linked or the linked person was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedPersonDto"}]},"organization":{"nullable":true,"description":"The linked organization. Null when none is linked or the linked organization was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedOrganizationDto"}]}},"required":["id","caseId","personId","organizationId","badgeNumber","supervisor","name","notes","creationTime","person","organization"]},"PoliceOfficerListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PoliceOfficerDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreatePoliceOfficerDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"badgeNumber":{"type":"string"},"supervisor":{"type":"string","maxLength":150,"description":"Legacy PoliceOfficer.Supervisor."},"name":{"type":"string"},"notes":{"type":"string"}}},"UpdatePoliceOfficerDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"badgeNumber":{"type":"string"},"supervisor":{"type":"string","maxLength":150,"description":"Legacy PoliceOfficer.Supervisor."},"name":{"type":"string"},"notes":{"type":"string"}}},"ProsecutorDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"name":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"person":{"nullable":true,"description":"The linked person. Null when none is linked or the linked person was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedPersonDto"}]},"organization":{"nullable":true,"description":"The linked organization. Null when none is linked or the linked organization was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedOrganizationDto"}]}},"required":["id","caseId","personId","organizationId","name","notes","creationTime","person","organization"]},"ProsecutorListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ProsecutorDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateProsecutorDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"name":{"type":"string"},"notes":{"type":"string"}}},"UpdateProsecutorDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"name":{"type":"string"},"notes":{"type":"string"}}},"BondsmanDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"name":{"type":"object","nullable":true},"bondAmount":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"person":{"nullable":true,"description":"The linked person. Null when none is linked or the linked person was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedPersonDto"}]},"organization":{"nullable":true,"description":"The linked organization. Null when none is linked or the linked organization was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedOrganizationDto"}]}},"required":["id","caseId","personId","organizationId","name","bondAmount","notes","creationTime","person","organization"]},"BondsmanListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BondsmanDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateBondsmanDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"name":{"type":"string"},"bondAmount":{"type":"string","description":"Decimal bond amount as a string."},"notes":{"type":"string"}}},"UpdateBondsmanDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"name":{"type":"string"},"bondAmount":{"type":"string","description":"Decimal bond amount as a string."},"notes":{"type":"string"}}},"RollCallLocationDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"personId":{"type":"string","nullable":true},"organizationId":{"type":"number","nullable":true},"notes":{"type":"string","nullable":true},"creationTime":{"format":"date-time","type":"string"},"person":{"nullable":true,"description":"The linked person. Null when none is linked or the linked person was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedPersonDto"}]},"organization":{"nullable":true,"description":"The linked organization. Null when none is linked or the linked organization was deleted.","type":"object","allOf":[{"$ref":"#/components/schemas/LinkedOrganizationDto"}]}},"required":["id","caseId","personId","organizationId","notes","creationTime","person","organization"]},"RollCallLocationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RollCallLocationDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateRollCallLocationDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"notes":{"type":"string","description":"API-only extra with no legacy equivalent."}}},"UpdateRollCallLocationDto":{"type":"object","properties":{"personId":{"type":"string","description":"Person id as a string (bigint)."},"organizationId":{"type":"number"},"notes":{"type":"string","description":"API-only extra with no legacy equivalent."}}},"HistoryRequestDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"providerId":{"type":"object","nullable":true},"target":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"requestedDate":{"type":"object","nullable":true},"receivedDate":{"type":"object","nullable":true},"reminder":{"type":"object","nullable":true},"reminderDate":{"type":"object","nullable":true},"providerName":{"type":"object","nullable":true},"status":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","caseId","providerId","target","description","requestedDate","receivedDate","reminder","reminderDate","providerName","status","creationTime"]},"HistoryRequestListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/HistoryRequestDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateHistoryRequestDto":{"type":"object","properties":{"providerId":{"type":"number"},"target":{"type":"string","nullable":true,"description":"Null clears it on update."},"description":{"type":"string","nullable":true,"description":"Null clears it on update."},"requestedDate":{"type":"string","nullable":true,"description":"ISO date the records were requested. Null clears it on update."},"receivedDate":{"type":"string","nullable":true,"description":"ISO date the records were received. Null clears it on update."},"reminder":{"type":"boolean","description":"Whether a follow-up reminder is set."},"reminderDate":{"type":"string","nullable":true,"description":"ISO date of the follow-up reminder. Null clears it on update."},"status":{"type":"string"}},"required":["providerId"]},"UpdateHistoryRequestDto":{"type":"object","properties":{"providerId":{"type":"number"},"target":{"type":"string","nullable":true,"description":"Null clears it on update."},"description":{"type":"string","nullable":true,"description":"Null clears it on update."},"requestedDate":{"type":"string","nullable":true,"description":"ISO date the records were requested. Null clears it on update."},"receivedDate":{"type":"string","nullable":true,"description":"ISO date the records were received. Null clears it on update."},"reminder":{"type":"boolean","description":"Whether a follow-up reminder is set."},"reminderDate":{"type":"string","nullable":true,"description":"ISO date of the follow-up reminder. Null clears it on update."},"status":{"type":"string"}},"required":["providerId"]},"CaseHistoryDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"historyRequestId":{"type":"object","nullable":true},"note":{"type":"string"},"historyDate":{"format":"date-time","type":"string"},"creationTime":{"format":"date-time","type":"string"}},"required":["id","caseId","historyRequestId","note","historyDate","creationTime"]},"CaseHistoryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/CaseHistoryDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateCaseHistoryDto":{"type":"object","properties":{"note":{"type":"string"},"historyDate":{"type":"string","description":"ISO date of the history entry."}},"required":["note","historyDate"]},"UpdateCaseHistoryDto":{"type":"object","properties":{"note":{"type":"string"},"historyDate":{"type":"string","description":"ISO date of the history entry."}}},"StateDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"abbreviation":{"type":"string"}},"required":["id","name","abbreviation"]},"CodeLookupDto":{"type":"object","properties":{"id":{"type":"number"},"code":{"type":"object","nullable":true},"description":{"type":"string"}},"required":["id","code","description"]},"LookupItemDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"}},"required":["id","name"]},"TimeEntryDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"object","nullable":true},"assignedToUserId":{"type":"string"},"billingStatusId":{"type":"number"},"billingCodeId":{"type":"object","nullable":true},"ledesActivityId":{"type":"object","nullable":true},"ledesTaskId":{"type":"object","nullable":true},"rateTypeId":{"type":"object","nullable":true},"startDate":{"format":"date-time","type":"string"},"endDate":{"type":"object","nullable":true},"totalTime":{"type":"object","nullable":true,"description":"Hours (decimal string)."},"timeAdjustment":{"type":"object","nullable":true},"rate":{"type":"object","nullable":true},"totalAmount":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"internalDescription":{"type":"object","nullable":true},"posted":{"type":"boolean"},"prebill":{"type":"boolean"},"exported":{"type":"boolean"},"hold":{"type":"boolean"},"timeSheetId":{"type":"object","nullable":true},"invoiceId":{"type":"object","nullable":true},"timeEntryStageId":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Joined Case.caseStyle."},"caseKey":{"type":"number","nullable":true,"description":"Joined Case.caseKey: the case number shown in case URLs (GET /cases/key/{key})."},"timekeeperName":{"type":"object","nullable":true,"description":"Timekeeper full name (assignedToUserId -> User)."},"activityCode":{"type":"object","nullable":true,"description":"Joined LedesActivity.code."},"activityDescription":{"type":"object","nullable":true,"description":"Joined LedesActivity.description."},"taskCode":{"type":"object","nullable":true,"description":"Joined LedesTask.code."},"taskBrief":{"type":"object","nullable":true,"description":"Joined LedesTask.codeBrief."},"isEditable":{"type":"boolean","description":"True when the acting user may edit this entry from their own time screens: they are the timekeeper and the entry is Open or Rejected, or approval is bypassed and it is not yet pre-billed, invoiced or paid (legacy GetAllTimers IsEditable). Billing staff edit other entries from the billing screens."},"isFixedFee":{"type":"boolean","description":"True for the case's fixed-fee line on an invoice (no hours; rate and amount are the fee billed). It lists only with its invoice and is changed from the invoice's fixedFeeAmount, not from the time screens."}},"required":["id","caseId","assignedToUserId","billingStatusId","billingCodeId","ledesActivityId","ledesTaskId","rateTypeId","startDate","endDate","totalTime","timeAdjustment","rate","totalAmount","description","internalDescription","posted","prebill","exported","hold","timeSheetId","invoiceId","timeEntryStageId","creationTime","caseStyle","caseKey","timekeeperName","activityCode","activityDescription","taskCode","taskBrief","isEditable","isFixedFee"]},"TimeEntryListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TimeEntryDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateTimeEntryDto":{"type":"object","properties":{"caseId":{"type":"number","description":"Case the entry is billed to."},"assignedToUserId":{"type":"string","description":"Timekeeper (bigint user id). Defaults to the acting user."},"billingStatusId":{"type":"number","description":"Billing status (global enum id)."},"billingCodeId":{"type":"number"},"ledesActivityId":{"type":"number"},"ledesTaskId":{"type":"number"},"rateTypeId":{"type":"number"},"startDate":{"type":"string","example":"2026-06-04T09:00:00.000Z"},"endDate":{"type":"string","example":"2026-06-04T10:30:00.000Z"},"totalTime":{"type":"string","description":"Hours, decimal string e.g. \"1.50\"."},"timeAdjustment":{"type":"string","description":"Hour adjustment, decimal string."},"rate":{"type":"string","description":"Hourly rate, decimal string."},"totalAmount":{"type":"string","description":"Fee amount, decimal string."},"description":{"type":"string"},"internalDescription":{"type":"string"},"hold":{"type":"boolean"},"preBillId":{"type":"number","description":"Attach the new entry to this pre-bill (forces Pre-Bill stage). Case defaults from the pre-bill when omitted."},"invoiceId":{"type":"number","description":"Add the new entry to this invoice (billing screen; forces the Invoiced stage). Case defaults from the invoice when omitted. On a fixed-fee invoice the entry keeps the rate sent in `rate` when Billable and rates to 0 otherwise."}},"required":["billingStatusId","startDate"]},"StartTimerDto":{"type":"object","properties":{"billingStatusId":{"type":"number"},"caseId":{"type":"number"},"billingCodeId":{"type":"number"},"assignedToUserId":{"type":"string"},"description":{"type":"string"}},"required":["billingStatusId"]},"UpdateTimeEntryDto":{"type":"object","properties":{"caseId":{"type":"number"},"billingStatusId":{"type":"number"},"billingCodeId":{"type":"number","nullable":true,"description":"Send null to clear it."},"ledesActivityId":{"type":"number","nullable":true,"description":"Send null to clear it."},"ledesTaskId":{"type":"number","nullable":true,"description":"Send null to clear it."},"rateTypeId":{"type":"number"},"startDate":{"type":"string"},"endDate":{"type":"string","nullable":true,"description":"ISO date-time; send null to clear the end and set the timer running again."},"totalTime":{"type":"string"},"timeAdjustment":{"type":"string"},"rate":{"type":"string"},"totalAmount":{"type":"string"},"description":{"type":"string","nullable":true,"description":"Send null to clear it."},"internalDescription":{"type":"string","nullable":true,"description":"Send null to clear it."},"hold":{"type":"boolean"}}},"TimeSheetWeekDto":{"type":"object","properties":{"userId":{"type":"string","description":"Timekeeper (bigint user id)."},"timekeeperName":{"type":"object","nullable":true},"year":{"type":"number"},"week":{"type":"number","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year."},"periodStart":{"type":"string","description":"First day of the week (YYYY-MM-DD).","example":"2026-05-31"},"periodEnd":{"type":"string","description":"Last day of the week (YYYY-MM-DD, inclusive).","example":"2026-06-06"},"dateRange":{"type":"string","description":"Legacy label \"MM/dd/yyyy - MM/dd/yyyy\"."},"stage":{"type":"string","enum":["Open","Submitted","Rejected","Approved"]},"timeSheetId":{"type":"object","nullable":true,"description":"time_sheets row id once submitted, approved or rejected."},"hours":{"type":"string","description":"Sum of totalTime (legacy \"Hours\")."},"hoursEntered":{"type":"string","description":"Sum of totalTime + timeAdjustment (legacy \"Hours Entered\")."},"billableHours":{"type":"string","description":"Sum of totalTime over Billable entries."},"billableHoursEntered":{"type":"string","description":"Sum of totalTime + timeAdjustment over Billable entries."},"canSubmit":{"type":"boolean","description":"The acting user may submit this week now."}},"required":["userId","timekeeperName","year","week","periodStart","periodEnd","dateRange","stage","timeSheetId","hours","hoursEntered","billableHours","billableHoursEntered","canSubmit"]},"TimeSheetWeekListDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TimeSheetWeekDto"}},"approvalBypassed":{"type":"boolean","description":"Tenant billing setting: approval is bypassed, so unbilled time can be pre-billed without submitting time sheets (submit and approve still work)."}},"required":["items","approvalBypassed"]},"TimeSheetWeekListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TimeSheetWeekDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"},"approvalBypassed":{"type":"boolean","description":"Tenant billing setting: approval is bypassed, so unbilled time can be pre-billed without submitting time sheets (submit and approve still work)."}},"required":["items","meta","approvalBypassed"]},"TimeSheetDayDto":{"type":"object","properties":{"date":{"type":"string","example":"2026-05-31"},"hours":{"type":"string","description":"Sum of totalTime that day."},"hoursEntered":{"type":"string","description":"Sum of totalTime + timeAdjustment that day."}},"required":["date","hours","hoursEntered"]},"TimeSheetWeekDetailDto":{"type":"object","properties":{"userId":{"type":"string","description":"Timekeeper (bigint user id)."},"timekeeperName":{"type":"object","nullable":true},"year":{"type":"number"},"week":{"type":"number","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year."},"periodStart":{"type":"string","description":"First day of the week (YYYY-MM-DD).","example":"2026-05-31"},"periodEnd":{"type":"string","description":"Last day of the week (YYYY-MM-DD, inclusive).","example":"2026-06-06"},"dateRange":{"type":"string","description":"Legacy label \"MM/dd/yyyy - MM/dd/yyyy\"."},"stage":{"type":"string","enum":["Open","Submitted","Rejected","Approved"]},"timeSheetId":{"type":"object","nullable":true,"description":"time_sheets row id once submitted, approved or rejected."},"hours":{"type":"string","description":"Sum of totalTime (legacy \"Hours\")."},"hoursEntered":{"type":"string","description":"Sum of totalTime + timeAdjustment (legacy \"Hours Entered\")."},"billableHours":{"type":"string","description":"Sum of totalTime over Billable entries."},"billableHoursEntered":{"type":"string","description":"Sum of totalTime + timeAdjustment over Billable entries."},"canSubmit":{"type":"boolean","description":"The acting user may submit this week now."},"days":{"description":"One row per day of the period, Sunday first.","type":"array","items":{"$ref":"#/components/schemas/TimeSheetDayDto"}},"totalHours":{"type":"string","description":"Same as hoursEntered."},"totalBillable":{"type":"string","description":"Same as billableHoursEntered."},"entries":{"type":"array","items":{"$ref":"#/components/schemas/TimeEntryDto"}},"canApprove":{"type":"boolean","description":"The acting user may approve or reject this week now."},"canUndoApproval":{"type":"boolean","description":"The acting user may undo the approval now (Approved and nothing pre-billed or invoiced)."},"approvalBypassed":{"type":"boolean","description":"Tenant billing setting: approval is bypassed, so unbilled time can be pre-billed without submitting time sheets (submit and approve still work)."}},"required":["userId","timekeeperName","year","week","periodStart","periodEnd","dateRange","stage","timeSheetId","hours","hoursEntered","billableHours","billableHoursEntered","canSubmit","days","totalHours","totalBillable","entries","canApprove","canUndoApproval","approvalBypassed"]},"CreateTimeSheetDto":{"type":"object","properties":{"assignedToUserId":{"type":"string","description":"Timekeeper (bigint user id). Defaults to acting user."},"year":{"type":"number","example":2026},"week":{"type":"number","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year.","example":23}},"required":["year","week"]},"TimeSheetDto":{"type":"object","properties":{"id":{"type":"number"},"assignedToUserId":{"type":"string"},"timeSheetStageId":{"type":"number"},"stage":{"type":"object","nullable":true,"description":"Stage name when resolved."},"year":{"type":"number"},"week":{"type":"number","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year."},"creationTime":{"format":"date-time","type":"string"},"timekeeperName":{"type":"object","nullable":true,"description":"Timekeeper full name (assignedToUserId -> User)."},"dateRange":{"type":"object","nullable":true,"description":"Sun-Sat date range of the en-US year/week (\"MM/dd/yyyy - MM/dd/yyyy\")."},"hoursEntered":{"type":"string","description":"Sum of (totalTime + timeAdjustment) over attached time entries."},"billableHoursEntered":{"type":"string","description":"Sum of (totalTime + timeAdjustment) over Billable time entries."}},"required":["id","assignedToUserId","timeSheetStageId","stage","year","week","creationTime","timekeeperName","dateRange","hoursEntered","billableHoursEntered"]},"UpdateTimeSheetDto":{"type":"object","properties":{"year":{"type":"number"},"week":{"type":"number","description":"en-US week of the year (1-54): weeks start on Sunday and week 1 is the week containing January 1, clamped to the calendar year."}}},"DescribedLookupDto":{"type":"object","properties":{"id":{"type":"number"},"description":{"type":"string"}},"required":["id","description"]},"LedesCodeDto":{"type":"object","properties":{"id":{"type":"number"},"code":{"type":"string"},"description":{"type":"object","nullable":true}},"required":["id","code","description"]},"BillingCodeDto":{"type":"object","properties":{"id":{"type":"number"},"code":{"type":"string"},"description":{"type":"object","nullable":true},"activityId":{"type":"object","nullable":true},"taskId":{"type":"object","nullable":true},"activityCode":{"type":"object","nullable":true},"activityDescription":{"type":"object","nullable":true},"taskCode":{"type":"object","nullable":true},"taskDescription":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","code","description","activityId","taskId","activityCode","activityDescription","taskCode","taskDescription","creationTime"]},"AbbreviationDto":{"type":"object","properties":{"id":{"type":"number"},"code":{"type":"string"},"phrase":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","code","phrase","creationTime"]},"FeeTypeDto":{"type":"object","properties":{"id":{"type":"number"},"code":{"type":"object","nullable":true},"name":{"type":"object","nullable":true},"description":{"type":"object","nullable":true}},"required":["id","code","name","description"]},"BillingEntityListItemDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"object","nullable":true},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"billingRate":{"type":"object","nullable":true},"firmRate":{"type":"object","nullable":true},"rateTypeId":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"isRestricted":{"type":"boolean"},"billingNotes":{"type":"object","nullable":true},"showOutstandingInvoices":{"type":"boolean"},"isParent":{"type":"boolean"},"parentBillingEntityId":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"billingContactName":{"type":"object","nullable":true,"description":"Resolved person/organization billing-contact name."},"balance":{"type":"string","description":"Outstanding balance (includes child entities for parents)."}},"required":["id","name","personId","organizationId","billingRate","firmRate","rateTypeId","isActive","isRestricted","billingNotes","showOutstandingInvoices","isParent","parentBillingEntityId","creationTime","billingContactName","balance"]},"BillingEntityListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityListItemDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateBillingEntityDto":{"type":"object","properties":{"name":{"type":"string","maxLength":100,"description":"Entity display name. Required and nonblank."},"personId":{"type":"string","description":"Linked person (bigint id). Must reference an existing person."},"organizationId":{"type":"number","description":"Linked organization id. Must reference an existing organization."},"billingRate":{"type":"string","description":"Hourly billing rate (decimal string)."},"firmRate":{"type":"string","description":"Fixed fee amount (decimal string), billed once per case, whole or in instalments. Required, above zero, when rateTypeId is 1 (Fixed Fee)."},"rateTypeId":{"type":"number","description":"Rate type id (global enum: 1 FixedFee .. 5 Contingency)."},"isActive":{"type":"boolean","default":true},"isRestricted":{"type":"boolean","default":false},"billingNotes":{"type":"string"},"showOutstandingInvoices":{"type":"boolean","default":false},"isParent":{"type":"boolean","default":false},"parentBillingEntityId":{"type":"number","description":"Parent billing entity id (hierarchy)."}},"required":["name"]},"BillingEntityDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"object","nullable":true},"personId":{"type":"object","nullable":true},"organizationId":{"type":"object","nullable":true},"billingRate":{"type":"object","nullable":true},"firmRate":{"type":"object","nullable":true},"rateTypeId":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"isRestricted":{"type":"boolean"},"billingNotes":{"type":"object","nullable":true},"showOutstandingInvoices":{"type":"boolean"},"isParent":{"type":"boolean"},"parentBillingEntityId":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","name","personId","organizationId","billingRate","firmRate","rateTypeId","isActive","isRestricted","billingNotes","showOutstandingInvoices","isParent","parentBillingEntityId","creationTime"]},"BillingEntityContactCardDto":{"type":"object","properties":{"name":{"type":"object","nullable":true},"line1":{"type":"object","nullable":true},"line2":{"type":"object","nullable":true},"city":{"type":"object","nullable":true},"stateCode":{"type":"object","nullable":true},"postalCode":{"type":"object","nullable":true},"email":{"type":"object","nullable":true},"phone":{"type":"object","nullable":true},"phoneExtension":{"type":"object","nullable":true},"fax":{"type":"object","nullable":true}},"required":["name","line1","line2","city","stateCode","postalCode","email","phone","phoneExtension","fax"]},"BillingEntitySummaryDto":{"type":"object","properties":{"balance":{"type":"string","description":"Every invoice's balance added up, an overpaid invoice's as a negative: the four aging buckets' total."},"retainerBalance":{"type":"string"},"agingThirty":{"type":"string"},"agingSixty":{"type":"string"},"agingNinety":{"type":"string"},"agingNinetyPlus":{"type":"string"},"unbilledHours":{"type":"string","description":"Unbilled billable hours (time entries not yet on an invoice)."},"totalTimeBilled":{"type":"string","description":"Total billable hours that have been invoiced."},"totalAmountBilled":{"type":"string","description":"Fees and billable expenses on the entity's invoices, each invoice rounded to cents at its total (Entity Payment's amount billed)."}},"required":["balance","retainerBalance","agingThirty","agingSixty","agingNinety","agingNinetyPlus","unbilledHours","totalTimeBilled","totalAmountBilled"]},"BillingEntityTimeKeeperRateDto":{"type":"object","properties":{"id":{"type":"object","nullable":true},"timeKeeperId":{"type":"object","nullable":true},"timeKeeperName":{"type":"object","nullable":true},"rate":{"type":"object","nullable":true}},"required":["id","timeKeeperId","timeKeeperName","rate"]},"BillingEntityTaskRateDto":{"type":"object","properties":{"id":{"type":"object","nullable":true},"ledesTaskId":{"type":"object","nullable":true},"ledesTaskCode":{"type":"object","nullable":true},"ledesTaskDescription":{"type":"object","nullable":true},"rate":{"type":"object","nullable":true}},"required":["id","ledesTaskId","ledesTaskCode","ledesTaskDescription","rate"]},"BillingEntityCaseDto":{"type":"object","properties":{"id":{"type":"number"},"caseNumber":{"type":"string"},"isActive":{"type":"boolean"},"isFinal":{"type":"boolean"},"caseStyle":{"type":"object","nullable":true},"caseKey":{"type":"number","description":"The case number shown in case URLs (Case.caseKey)."},"caseTypeName":{"type":"object","nullable":true},"assignedToName":{"type":"object","nullable":true},"balance":{"type":"object","nullable":true,"description":"Outstanding balance on this case (decimal string)."},"unbilledHours":{"type":"object","nullable":true,"description":"Unbilled billable hours on this case."},"billedAmount":{"type":"object","nullable":true,"description":"Invoiced billable fee amount on this case."}},"required":["id","caseNumber","isActive","isFinal","caseStyle","caseKey","caseTypeName","assignedToName","balance","unbilledHours","billedAmount"]},"BillingEntityInvoiceDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"invoiceNumber":{"type":"number"},"displayNumber":{"type":"string","description":"Invoice prefix + number, as shown to people."},"invoiceDate":{"format":"date-time","type":"string"},"isFinal":{"type":"boolean"}},"required":["id","caseId","invoiceNumber","displayNumber","invoiceDate","isFinal"]},"BillingEntityDetailDto":{"type":"object","properties":{"entity":{"$ref":"#/components/schemas/BillingEntityDto"},"organization":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/BillingEntityContactCardDto"}]},"contact":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/BillingEntityContactCardDto"}]},"summary":{"$ref":"#/components/schemas/BillingEntitySummaryDto"},"timeKeeperRates":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityTimeKeeperRateDto"}},"taskRates":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityTaskRateDto"}},"cases":{"description":"The cases billed to the entity. Without Cases.ViewAll, only the caller's own (ADR-0012); the summary and invoices still cover every case.","type":"array","items":{"$ref":"#/components/schemas/BillingEntityCaseDto"}},"invoices":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityInvoiceDto"}}},"required":["entity","organization","contact","summary","timeKeeperRates","taskRates","cases","invoices"]},"BillingEntityTransactionAllocationDto":{"type":"object","properties":{"invoiceId":{"type":"number"},"invoiceNumber":{"type":"string","description":"Invoice prefix + number, as shown to people."},"paid":{"type":"string","description":"Cash applied to the invoice (decimal string)."},"writtenOff":{"type":"string","description":"Written off on the invoice (decimal string)."}},"required":["invoiceId","invoiceNumber","paid","writtenOff"]},"BillingEntityTransactionStatementDto":{"type":"object","properties":{"id":{"type":"number"},"periodStart":{"format":"date-time","type":"string"},"periodEnd":{"format":"date-time","type":"string"},"totalBilled":{"type":"string"},"totalCollected":{"type":"string"},"balance":{"type":"string"}},"required":["id","periodStart","periodEnd","totalBilled","totalCollected","balance"]},"BillingEntityTransactionDto":{"type":"object","properties":{"key":{"type":"string","description":"Unique within the history, e.g. invoice-12."},"type":{"type":"string","enum":["invoice","payment","invoice_payment","statement"],"description":"invoice; payment (money received from the entity, with the invoices it paid and any retainer movement); invoice_payment (a payment recorded straight on one invoice); statement (a dated marker that moves no balance)."},"date":{"format":"date-time","type":"string"},"reference":{"type":"string","nullable":true,"description":"Invoice number (prefix + number) for invoice and invoice_payment lines."},"description":{"type":"string","nullable":true},"checkNumber":{"type":"string","nullable":true},"caseKey":{"type":"number","nullable":true,"description":"The invoice's case key (the number in case URLs), only when the caller may see it (ADR-0012)."},"caseLabel":{"type":"string","nullable":true},"invoiceId":{"type":"number","nullable":true},"billingEntityPaymentId":{"type":"number","nullable":true},"status":{"type":"string","nullable":true,"description":"Invoice stage name."},"received":{"type":"string","nullable":true,"description":"Cash received (decimal string)."},"billed":{"type":"string","nullable":true,"description":"Invoice total (decimal string)."},"paid":{"type":"string","nullable":true,"description":"Cash applied to invoices (decimal string)."},"writtenOff":{"type":"string","nullable":true,"description":"Written off on invoices (decimal string)."},"retainer":{"type":"string","nullable":true,"description":"Retainer movement: credits minus debits, negative when retainer was used."},"balance":{"type":"string","description":"Outstanding invoice balance after this line (decimal string)."},"retainerBalance":{"type":"string","description":"Retainer balance after this line (decimal string)."},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/BillingEntityTransactionAllocationDto"}},"statement":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/BillingEntityTransactionStatementDto"}]}},"required":["key","type","date","reference","description","checkNumber","caseKey","caseLabel","invoiceId","billingEntityPaymentId","status","received","billed","paid","writtenOff","retainer","balance","retainerBalance","allocations","statement"]},"BillingEntityTransactionsTotalsDto":{"type":"object","properties":{"billed":{"type":"string"},"paid":{"type":"string"},"writtenOff":{"type":"string"},"balance":{"type":"string","description":"Billed minus paid minus written off."},"retainerBalance":{"type":"string"}},"required":["billed","paid","writtenOff","balance","retainerBalance"]},"BillingEntityTransactionListResponseDto":{"type":"object","properties":{"items":{"description":"Newest first.","type":"array","items":{"$ref":"#/components/schemas/BillingEntityTransactionDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"},"totals":{"$ref":"#/components/schemas/BillingEntityTransactionsTotalsDto"}},"required":["items","meta","totals"]},"SetBillingEntityRateDto":{"type":"object","properties":{"rate":{"type":"object","nullable":true,"description":"Decimal rate as a string; null removes the stored rate."}},"required":["rate"]},"UpdateBillingEntityDto":{"type":"object","properties":{"name":{"type":"string","maxLength":100},"personId":{"type":"string"},"organizationId":{"type":"number"},"billingRate":{"type":"string"},"firmRate":{"type":"string"},"rateTypeId":{"type":"number"},"isActive":{"type":"boolean"},"isRestricted":{"type":"boolean"},"billingNotes":{"type":"string"},"showOutstandingInvoices":{"type":"boolean"},"isParent":{"type":"boolean"},"parentBillingEntityId":{"type":"number"}}},"PaymentDto":{"type":"object","properties":{"id":{"type":"number"},"billingEntityPaymentId":{"type":"object","nullable":true},"invoiceId":{"type":"number"},"paymentDate":{"format":"date-time","type":"string"},"paymentAmount":{"type":"string"},"checkNumber":{"type":"object","nullable":true},"feeTypeId":{"type":"object","nullable":true},"feesPaid":{"type":"object","nullable":true},"expensesPaid":{"type":"object","nullable":true},"feesWriteOff":{"type":"object","nullable":true},"expensesWriteOff":{"type":"object","nullable":true},"billingEntityName":{"type":"object","nullable":true,"description":"Billing entity name, resolved via the parent billing-entity payment."},"description":{"type":"object","nullable":true,"description":"Description from the parent billing-entity payment."},"creationTime":{"format":"date-time","type":"string"}},"required":["id","billingEntityPaymentId","invoiceId","paymentDate","paymentAmount","checkNumber","feeTypeId","feesPaid","expensesPaid","feesWriteOff","expensesWriteOff","creationTime"]},"PaymentListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PaymentDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"PaymentReceivedDto":{"type":"object","properties":{"kind":{"type":"string","enum":["entity","invoice"]},"id":{"type":"number"},"paymentDate":{"format":"date-time","type":"string"},"billingEntityId":{"type":"object","nullable":true},"billingEntityName":{"type":"object","nullable":true},"checkNumber":{"type":"object","nullable":true},"paymentAmount":{"type":"string","description":"The amount received."},"description":{"type":"object","nullable":true}},"required":["kind","id","paymentDate","billingEntityId","billingEntityName","checkNumber","paymentAmount","description"]},"PaymentReceivedListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/PaymentReceivedDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreatePaymentDto":{"type":"object","properties":{"invoiceId":{"type":"number","description":"Invoice this payment applies to."},"paymentDate":{"type":"string"},"paymentAmount":{"type":"string","description":"Total cash received, decimal string. Sent without feesPaid, expensesPaid or write-offs, it is applied to what the invoice owes, fees first, then expenses; an overpayment stays on the fees."},"checkNumber":{"type":"string"},"feeTypeId":{"type":"number"},"feesPaid":{"type":"string","description":"Fees paid, decimal string."},"expensesPaid":{"type":"string","description":"Expenses paid, decimal string."},"feesWriteOff":{"type":"string","description":"Fees written off, decimal string."},"expensesWriteOff":{"type":"string","description":"Expenses written off, decimal string."}},"required":["invoiceId","paymentDate"]},"UpdatePaymentDto":{"type":"object","properties":{"paymentDate":{"type":"string"},"paymentAmount":{"type":"string"},"checkNumber":{"type":"string"},"feeTypeId":{"type":"number"},"feesPaid":{"type":"string"},"expensesPaid":{"type":"string"},"feesWriteOff":{"type":"string"},"expensesWriteOff":{"type":"string"}}},"InvoiceOwedDto":{"type":"object","properties":{"invoiceId":{"type":"number"},"invoiceNumber":{"type":"number"},"displayNumber":{"type":"string","description":"Invoice prefix + number, as shown to people."},"invoiceDate":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Case label (case style) for the invoice."},"fees":{"type":"string","description":"Billable, non-held fee total on the invoice."},"expenses":{"type":"string","description":"Billable expense total (per-line rounded)."},"totalFeesPaid":{"type":"string"},"totalExpensesPaid":{"type":"string"},"totalFeesWriteOff":{"type":"string"},"totalExpensesWriteOff":{"type":"string"},"feesOwed":{"type":"string","description":"fees - feesPaid - feesWriteOff."},"expensesOwed":{"type":"string","description":"expenses - expensesPaid - expensesWriteOff."}},"required":["invoiceId","invoiceNumber","displayNumber","invoiceDate","caseStyle","fees","expenses","totalFeesPaid","totalExpensesPaid","totalFeesWriteOff","totalExpensesWriteOff","feesOwed","expensesOwed"]},"PaymentAllocationDto":{"type":"object","properties":{"billingEntityId":{"type":"number"},"invoices":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceOwedDto"}},"balance":{"type":"string","description":"Sum of fees + expenses owed across the listed invoices."},"retainerBalance":{"type":"string","description":"Retainer credits minus debits for the billing entity."},"totalThirty":{"type":"string","description":"Outstanding balance 0-30 days past due."},"totalSixty":{"type":"string","description":"Outstanding balance 31-60 days past due."},"totalNinety":{"type":"string","description":"Outstanding balance 61-90 days past due."},"totalNinetyPlus":{"type":"string","description":"Outstanding balance 91+ days past due."},"unbilledTime":{"type":"string","description":"Billable, non-held time hours not yet on an invoice."},"totalTimeBilled":{"type":"string","description":"Billable, non-held time hours already on an invoice."},"totalAmountBilled":{"type":"string","description":"Total fees + expenses billed across the entity invoices."}},"required":["billingEntityId","invoices","balance","retainerBalance","totalThirty","totalSixty","totalNinety","totalNinetyPlus","unbilledTime","totalTimeBilled","totalAmountBilled"]},"RetainerInputDto":{"type":"object","properties":{"credit":{"type":"string","description":"Retainer credit (money in), decimal string."},"debit":{"type":"string","description":"Retainer debit (money applied), decimal string."}}},"PaymentAllocationInputDto":{"type":"object","properties":{"invoiceId":{"type":"number"},"feesPaid":{"type":"string"},"expensesPaid":{"type":"string"},"feesWriteOff":{"type":"string"},"expensesWriteOff":{"type":"string"}},"required":["invoiceId"]},"CreateBillingEntityPaymentDto":{"type":"object","properties":{"paymentDate":{"type":"string"},"paymentAmount":{"type":"string","description":"Total payment amount received, decimal string."},"checkNumber":{"type":"string"},"description":{"type":"string"},"notes":{"type":"string"},"retainer":{"$ref":"#/components/schemas/RetainerInputDto"},"allocations":{"type":"array","items":{"$ref":"#/components/schemas/PaymentAllocationInputDto"}}},"required":["paymentDate","paymentAmount","allocations"]},"RetainerDto":{"type":"object","properties":{"id":{"type":"number"},"billingEntityPaymentId":{"type":"number"},"credit":{"type":"object","nullable":true},"debit":{"type":"object","nullable":true}},"required":["id","billingEntityPaymentId","credit","debit"]},"BillingEntityPaymentDto":{"type":"object","properties":{"id":{"type":"number"},"billingEntityId":{"type":"number"},"paymentDate":{"format":"date-time","type":"string"},"paymentAmount":{"type":"string"},"checkNumber":{"type":"object","nullable":true},"writeOff":{"type":"boolean"},"description":{"type":"object","nullable":true},"notes":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"retainer":{"nullable":true,"type":"object","allOf":[{"$ref":"#/components/schemas/RetainerDto"}]},"payments":{"type":"array","items":{"$ref":"#/components/schemas/PaymentDto"}}},"required":["id","billingEntityId","paymentDate","paymentAmount","checkNumber","writeOff","description","notes","creationTime","retainer","payments"]},"RetainerLedgerAllocationDto":{"type":"object","properties":{"invoiceId":{"type":"number"},"displayNumber":{"type":"string","description":"Invoice number as displayed, with its prefix."},"paymentAmount":{"type":"string","description":"Cash applied to the invoice, decimal string."},"writeOff":{"type":"string","description":"Fees and expenses written off on the invoice, decimal string."}},"required":["invoiceId","displayNumber","paymentAmount","writeOff"]},"RetainerLedgerEntryDto":{"type":"object","properties":{"id":{"type":"number"},"billingEntityPaymentId":{"type":"number"},"credit":{"type":"object","nullable":true},"debit":{"type":"object","nullable":true},"paymentDate":{"format":"date-time","type":"string"},"paymentAmount":{"type":"string","description":"Total cash received on the entity payment, decimal string."},"checkNumber":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"allocations":{"description":"The invoices the entity payment was applied to, in invoice order.","type":"array","items":{"$ref":"#/components/schemas/RetainerLedgerAllocationDto"}}},"required":["id","billingEntityPaymentId","credit","debit","paymentDate","paymentAmount","checkNumber","description","allocations"]},"RetainerBalanceDto":{"type":"object","properties":{"billingEntityId":{"type":"number"},"balance":{"type":"string","description":"Retainer credits minus debits, decimal string."}},"required":["billingEntityId","balance"]},"BillableDto":{"type":"object","properties":{"caseId":{"type":"number"},"caseStyle":{"type":"object","nullable":true},"billingEntityId":{"type":"number"},"billingEntityName":{"type":"object","nullable":true},"startDate":{"type":"object","nullable":true,"description":"Earliest eligible timer startDate; for a case with expenses only, its earliest expense date."},"endDate":{"type":"object","nullable":true,"description":"Latest eligible timer startDate; for a case with expenses only, its latest expense date."},"timerCount":{"type":"number"},"totalHours":{"type":"string","description":"Sum of totalTime over eligible timers."},"timerAmount":{"type":"string","description":"Sum of totalAmount over eligible timers (services)."},"expenseAmount":{"type":"string","description":"Sum of in-range billable uninvoiced expense cost*quantity."},"fixedFeeAmount":{"type":"string","description":"Deprecated: always \"0.00\". The fixed fee is billed on its own invoice (POST /invoices/fixed-fee), not through Billables.","deprecated":true},"totalAmount":{"type":"string","description":"timerAmount + expenseAmount."}},"required":["caseId","caseStyle","billingEntityId","billingEntityName","startDate","endDate","timerCount","totalHours","timerAmount","expenseAmount","fixedFeeAmount","totalAmount"]},"BillableListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BillableDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"ExpenseDto":{"type":"object","properties":{"id":{"type":"number"},"caseId":{"type":"number"},"date":{"type":"object","nullable":true},"description":{"type":"object","nullable":true},"cost":{"type":"object","nullable":true,"description":"Unit cost (3 dp)."},"quantity":{"type":"object","nullable":true},"lineTotal":{"type":"object","nullable":true,"description":"cost * quantity rounded to cents (half up), matching legacy line total."},"billable":{"type":"object","nullable":true},"batch":{"type":"object","nullable":true},"invoiceId":{"type":"object","nullable":true},"expenseCode":{"type":"object","nullable":true},"ledesExpenseId":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"caseStyle":{"type":"object","nullable":true,"description":"Joined Case.caseStyle."},"ledesExpenseCode":{"type":"object","nullable":true,"description":"Joined LedesExpense.code."},"ledesExpenseDescription":{"type":"object","nullable":true,"description":"Joined LedesExpense.description."}},"required":["id","caseId","date","description","cost","quantity","lineTotal","billable","batch","invoiceId","expenseCode","ledesExpenseId","creationTime","caseStyle","ledesExpenseCode","ledesExpenseDescription"]},"ExpenseListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ExpenseDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateExpenseDto":{"type":"object","properties":{"caseId":{"type":"number","description":"Case (matter) the expense belongs to."},"date":{"type":"string"},"description":{"type":"string"},"cost":{"type":"string","description":"Unit cost, decimal string (3 dp stored)."},"quantity":{"type":"string","description":"Quantity, decimal string."},"billable":{"type":"boolean","description":"Whether the expense is billable to the client."},"batch":{"type":"boolean"},"expenseCode":{"type":"string"},"ledesExpenseId":{"type":"number","description":"LEDES expense code mapping."}},"required":["caseId"]},"UpdateExpenseDto":{"type":"object","properties":{"date":{"type":"string","nullable":true,"description":"Send null to clear it."},"description":{"type":"string","nullable":true,"description":"Send null to clear it."},"cost":{"type":"string","description":"Unit cost, decimal string (3 dp stored)."},"quantity":{"type":"string","description":"Quantity, decimal string."},"billable":{"type":"boolean"},"batch":{"type":"boolean"},"expenseCode":{"type":"string","nullable":true,"description":"Send null to clear it."},"ledesExpenseId":{"type":"number","nullable":true,"description":"Send null to clear it."}}},"LedesExportDto":{"type":"object","properties":{"fileName":{"type":"string","description":"Suggested download file name, e.g. invoice-10000.led."},"contentType":{"type":"string","description":"MIME type for the export body."},"format":{"type":"string","description":"LEDES 1998B format identifier."},"lineItemCount":{"type":"number","description":"Number of line items (fees + expenses) emitted."},"invoiceTotal":{"type":"string","description":"Invoice total, equal to the sum of line-item totals."},"content":{"type":"string","description":"The complete LEDES 1998B file body (CRLF line endings)."}},"required":["fileName","contentType","format","lineItemCount","invoiceTotal","content"]},"LedesProblemDto":{"type":"object","properties":{"statusCode":{"type":"number","example":400},"error":{"type":"string","example":"Bad Request"},"message":{"type":"string","description":"Title and detail joined as one sentence pair.","example":"Matter Id is required. Enter the Matter Id on the case billing tab."},"title":{"type":"string","example":"Matter Id is required"},"detail":{"type":"string","example":"Enter the Matter Id on the case billing tab"}},"required":["statusCode","error","message","title","detail"]},"DocumentTemplateDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"fileName":{"type":"string"},"contentType":{"type":"string","nullable":true},"sharepointDriveId":{"type":"string","nullable":true,"description":"Graph drive id holding the template file. Exposed so a live SharePoint folder listing can be matched against registered templates."},"sharepointItemId":{"type":"string","nullable":true,"description":"Graph item id of the template file. Pairs with sharepointDriveId for matching."},"sharepointWebUrl":{"type":"string","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","name","description","fileName","contentType","sharepointDriveId","sharepointItemId","sharepointWebUrl","creationTime"]},"CreateDocumentTemplateDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"fileName":{"type":"string","description":"Template .docx file name."},"contentType":{"type":"string"},"sharepointDriveId":{"type":"string","description":"SharePoint/Graph drive id holding the template."},"sharepointItemId":{"type":"string"},"sharepointWebUrl":{"type":"string","description":"Direct download/web URL for the template bytes."}},"required":["name","fileName"]},"UpdateDocumentTemplateDto":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"fileName":{"type":"string"},"contentType":{"type":"string"},"sharepointDriveId":{"type":"string"},"sharepointItemId":{"type":"string"},"sharepointWebUrl":{"type":"string"}}},"MergeFieldDto":{"type":"object","properties":{"token":{"type":"string","description":"The {token} / <<<token>>> name and the key in merge-data values."},"label":{"type":"string"},"type":{"type":"string","enum":["text","date","number","currency","boolean"]},"source":{"type":"string","enum":["case","special","participant","custom"]},"legacyToken":{"type":"string","nullable":true,"description":"Legacy spelling when it differs from token (for example Case_Style)."},"description":{"type":"string"},"entity":{"type":"string","description":"Entity name for dotted tokens (Plaintiff, Counsel, ...)."},"fieldId":{"type":"number","description":"CaseDetailField id for custom fields."},"sensitive":{"type":"boolean","description":"True for tokens that need People.ViewPii. They are omitted from merge data otherwise."}},"required":["token","label","type","source"]},"MergeFieldGroupDto":{"type":"object","properties":{"key":{"type":"string","description":"'case' | 'special' | '<Entity>' | 'custom:<detailClassId>'."},"label":{"type":"string"},"caseTypeId":{"type":"number","nullable":true,"description":"Custom groups only."},"fields":{"type":"array","items":{"$ref":"#/components/schemas/MergeFieldDto"}}},"required":["key","label","fields"]},"MergeFieldsDto":{"type":"object","properties":{"scalars":{"description":"Scalar {tokens} and legacy <<<tokens>>> available on every case merge.","type":"array","items":{"type":"string"}},"participantFields":{"description":"Sub-fields inside the {#participants}...{/participants} loop.","type":"array","items":{"type":"string"}},"detailFields":{"description":"Dynamic EAV detail field names (also available as {details.<name>} and {<name>}).","type":"array","items":{"type":"string"}},"groups":{"description":"Tokens grouped for pickers: case, one group per participant role, claim and medical, and custom detail groups.","type":"array","items":{"$ref":"#/components/schemas/MergeFieldGroupDto"}}},"required":["scalars","participantFields","detailFields","groups"]},"CreateMergeDto":{"type":"object","properties":{"caseId":{"type":"number","description":"Case to merge against."},"documentTemplateId":{"type":"number","description":"Registered template id. Provide this OR sharepointDriveId + sharepointItemId."},"sharepointDriveId":{"type":"string","description":"Graph drive id for an ad-hoc template file."},"sharepointItemId":{"type":"string","description":"Graph item id for an ad-hoc template file."},"fileName":{"type":"string","description":"File name of the ad-hoc template (.docx)."},"name":{"type":"string","description":"Display name for an auto-created template row."},"leaveUnfilledTokens":{"type":"boolean","deprecated":true,"description":"Deprecated and ignored: legacy <<<Field>>> tokens without data always stay as highlighted placeholders."}},"required":["caseId"]},"MergeEnqueuedDto":{"type":"object","properties":{"mergeId":{"type":"number","description":"DocumentMerge record id."},"jobId":{"type":"string","description":"Background job id when the merge was queued. Empty string when the merge completed synchronously."},"sharepointWebUrl":{"type":"string","description":"SharePoint web URL of the merged document when the merge completed in this request.","nullable":true},"status":{"type":"string","description":"pending | running | completed | failed. completed when sharepointWebUrl is set."}},"required":["mergeId","jobId"]},"MergeValidationResultDto":{"type":"object","properties":{"missingFields":{"description":"Legacy <<<Field>>> tokens with no merge data.","type":"array","items":{"type":"string"}},"filledFields":{"description":"Legacy <<<Field>>> tokens that have merge data.","type":"array","items":{"type":"string"}}},"required":["missingFields","filledFields"]},"DocumentMergeDto":{"type":"object","properties":{"id":{"type":"number"},"documentTemplateId":{"type":"number"},"caseId":{"type":"number"},"status":{"type":"string","description":"pending | running | completed | failed"},"jobId":{"type":"string","nullable":true},"outputFileName":{"type":"string","nullable":true},"sharepointDriveId":{"type":"string","nullable":true},"sharepointItemId":{"type":"string","nullable":true},"sharepointWebUrl":{"type":"string","nullable":true},"errorMessage":{"type":"string","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","documentTemplateId","caseId","status","jobId","outputFileName","sharepointDriveId","sharepointItemId","sharepointWebUrl","errorMessage","creationTime"]},"CaseMergeParticipantDto":{"type":"object","properties":{"role":{"type":"string","description":"Lower-case participant type, e.g. 'plaintiff', 'opposing_counsel'."},"firstName":{"type":"string"},"lastName":{"type":"string"},"middleName":{"type":"string"},"fullName":{"type":"string"},"companyName":{"type":"string"},"email":{"type":"string"},"phone":{"type":"string"},"fax":{"type":"string"},"address1":{"type":"string"},"address2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postalCode":{"type":"string"},"dob":{"type":"string"},"ssn":{"type":"string","description":"Only present when piiIncluded is true."}},"required":["role","firstName","lastName","middleName","fullName","companyName","email","phone","fax","address1","address2","city","state","postalCode","dob"]},"CaseMergeDataDto":{"type":"object","properties":{"caseId":{"type":"number"},"caseKey":{"type":"number","description":"The number shown in case URLs (differs from caseId for migrated cases)."},"caseNumber":{"type":"string"},"caseStyle":{"type":"string","nullable":true},"caseTypeId":{"type":"number","nullable":true},"webUrl":{"type":"string","description":"Link that opens the case in the CaseWizard web app."},"piiIncluded":{"type":"boolean","description":"False when SSN was withheld from values and participants."},"values":{"type":"object","additionalProperties":{"type":"string"},"description":"Every merge token (modern and legacy spellings) mapped to its text value."},"participants":{"type":"array","items":{"$ref":"#/components/schemas/CaseMergeParticipantDto"}},"generatedAt":{"type":"string","description":"ISO 8601 time the data was generated."}},"required":["caseId","caseKey","caseNumber","caseStyle","caseTypeId","webUrl","piiIncluded","values","participants","generatedAt"]},"ExportEnqueuedDto":{"type":"object","properties":{"entity":{"type":"string","description":"Entity exported."},"jobId":{"type":"string","description":"Background job id; poll /v1/reports/jobs/{jobId} for the .xlsx."}},"required":["entity","jobId"]},"PdfJobEnqueuedDto":{"type":"object","properties":{"jobId":{"type":"string","description":"Background job id; poll /v1/reports/jobs/{jobId} for the file."}},"required":["jobId"]},"DownloadPreBillsDto":{"type":"object","properties":{"search":{"type":"string","description":"Match case style, billing entity name, or numeric id."},"startDate":{"type":"string","example":"2026-05-01"},"endDate":{"type":"string","example":"2026-05-31"},"preBillIds":{"description":"Limit to specific pre-bill ids.","type":"array","items":{"type":"number"}}}},"PrintBatchInvoicesDto":{"type":"object","properties":{"invoiceIds":{"type":"array","items":{"type":"number"}}},"required":["invoiceIds"]},"ApiKeyDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"prefix":{"type":"string","description":"Public lookup prefix."},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":"string","nullable":true},"expiresAt":{"type":"string","nullable":true},"revokedAt":{"type":"string","nullable":true},"creationTime":{"type":"string"}},"required":["id","name","prefix","scopes","lastUsedAt","expiresAt","revokedAt","creationTime"]},"CreateApiKeyDto":{"type":"object","properties":{"name":{"type":"string","example":"CI pipeline key"},"scopes":{"type":"array","example":["cases:read","billing:read"],"items":{"type":"string","enum":["cases:read","cases:write","people:read","people:write","documents:read","documents:write","calendar:read","calendar:write","medical:read","medical:write","criminal:read","criminal:write","billing:read","billing:write","reports:read","reports:write","lookups:read","lookups:write","webhooks:read","webhooks:write"]}},"expiresAt":{"type":"string","description":"Optional ISO-8601 expiry timestamp."}},"required":["name","scopes"]},"IssuedApiKeyDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"prefix":{"type":"string","description":"Public lookup prefix."},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":"string","nullable":true},"expiresAt":{"type":"string","nullable":true},"revokedAt":{"type":"string","nullable":true},"creationTime":{"type":"string"},"key":{"type":"string","description":"The full secret key. Shown once; store it now."}},"required":["id","name","prefix","scopes","lastUsedAt","expiresAt","revokedAt","creationTime","key"]},"OAuthClientDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"clientId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"revokedAt":{"type":"string","nullable":true},"creationTime":{"type":"string"}},"required":["id","name","clientId","scopes","revokedAt","creationTime"]},"CreateOAuthClientDto":{"type":"object","properties":{"name":{"type":"string","example":"Partner integration"},"scopes":{"type":"array","example":["cases:read"],"items":{"type":"string","enum":["cases:read","cases:write","people:read","people:write","documents:read","documents:write","calendar:read","calendar:write","medical:read","medical:write","criminal:read","criminal:write","billing:read","billing:write","reports:read","reports:write","lookups:read","lookups:write","webhooks:read","webhooks:write"]}}},"required":["name","scopes"]},"CreatedOAuthClientDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"clientId":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"revokedAt":{"type":"string","nullable":true},"creationTime":{"type":"string"},"clientSecret":{"type":"string","description":"The client secret. Shown once; store it now."}},"required":["id","name","clientId","scopes","revokedAt","creationTime","clientSecret"]},"AbbreviationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AbbreviationDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateAbbreviationDto":{"type":"object","properties":{"code":{"type":"string","description":"Short code typed by the user (expanded into the phrase)."},"phrase":{"type":"string","description":"The phrase the code expands to."}},"required":["code"]},"UpdateAbbreviationDto":{"type":"object","properties":{"code":{"type":"string"},"phrase":{"type":"string"}}},"RoleDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"isStatic":{"type":"boolean"},"permissionIds":{"description":"Granted permission ids.","type":"array","items":{"type":"number"}},"creationTime":{"format":"date-time","type":"string"}},"required":["id","name","isStatic","permissionIds","creationTime"]},"RoleListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/RoleDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateRoleDto":{"type":"object","properties":{"name":{"type":"string"},"permissionIds":{"description":"Permission ids granted to the role.","type":"array","items":{"type":"number"}}},"required":["name"]},"UpdateRoleDto":{"type":"object","properties":{"name":{"type":"string"},"permissionIds":{"description":"Replaces the granted permission set when present.","type":"array","items":{"type":"number"}}}},"PermissionDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"displayName":{"type":"string"},"parentName":{"type":"object","nullable":true}},"required":["id","name","displayName","parentName"]},"UserDto":{"type":"object","properties":{"id":{"type":"string"},"userName":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"object","nullable":true},"lastName":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"shouldChangePasswordOnNextLogin":{"type":"boolean"},"emailConfirmed":{"type":"boolean","description":"Whether the linked identity email has been confirmed."},"lastLoginTime":{"type":"object","nullable":true,"description":"Most recent successful login for this identity, if any."},"roleIds":{"description":"Assigned role ids.","type":"array","items":{"type":"number"}},"userClassificationId":{"type":"number","nullable":true,"description":"LEDES timekeeper classification id."},"userClassificationCode":{"type":"string","nullable":true,"description":"LEDES timekeeper classification code (e.g. PT, AS)."},"timeKeeperId":{"type":"string","nullable":true,"description":"LEDES TIMEKEEPER_ID."},"isTwoFactorEnabled":{"type":"boolean","description":"Whether the firm's two-factor login policy applies to this user."},"creationTime":{"format":"date-time","type":"string"}},"required":["id","userName","email","firstName","lastName","isActive","shouldChangePasswordOnNextLogin","emailConfirmed","lastLoginTime","roleIds","userClassificationId","userClassificationCode","timeKeeperId","isTwoFactorEnabled","creationTime"]},"UserListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/UserDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateUserDto":{"type":"object","properties":{"userClassificationId":{"type":"number","nullable":true,"description":"LEDES timekeeper classification (GET /v1/lookups/user-classifications). null clears it."},"timeKeeperId":{"type":"string","nullable":true,"maxLength":20,"description":"LEDES TIMEKEEPER_ID. Blank or null falls back to the user initials on LEDES files."},"isTwoFactorEnabled":{"type":"boolean","description":"Whether the firm's two-factor login policy applies to this user. Defaults to true on create."},"userName":{"type":"string"},"email":{"type":"string"},"password":{"type":"string","description":"Initial password (hashed at rest). Omit to set a random password the user never sees (legacy \"Set random password\"); send an activation email so they can choose their own. Ignored when the email already belongs to a CaseWizard account: an existing password is never overwritten."},"sendActivationEmail":{"type":"boolean","description":"Email the user a link to confirm their address and set a password. The password itself is never emailed."},"firstName":{"type":"string"},"lastName":{"type":"string"},"shouldChangePasswordOnNextLogin":{"type":"boolean","description":"Force a password change on next login."},"isActive":{"type":"boolean","description":"Whether the membership starts active. Defaults to true."},"roleIds":{"description":"Role ids to assign.","type":"array","items":{"type":"number"}}},"required":["userName","email"]},"UpdateUserDto":{"type":"object","properties":{"userClassificationId":{"type":"number","nullable":true,"description":"LEDES timekeeper classification (GET /v1/lookups/user-classifications). null clears it."},"timeKeeperId":{"type":"string","nullable":true,"maxLength":20,"description":"LEDES TIMEKEEPER_ID. Blank or null falls back to the user initials on LEDES files."},"isTwoFactorEnabled":{"type":"boolean","description":"Whether the firm's two-factor login policy applies to this user. Defaults to true on create."},"email":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"isActive":{"type":"boolean"},"shouldChangePasswordOnNextLogin":{"type":"boolean","description":"Force a password change on next login."},"password":{"type":"string","description":"Set a new password."},"sendActivationEmail":{"type":"boolean","description":"Email the user a fresh link to confirm their address (and set a password if they have never chosen one). The password itself is never emailed."},"roleIds":{"description":"Replaces the assigned roles when present.","type":"array","items":{"type":"number"}}}},"UserLookupDto":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"Full name, falling back to the username."}},"required":["id","name"]},"NotificationDto":{"type":"object","properties":{"id":{"type":"string"},"userId":{"type":"object","nullable":true},"title":{"type":"string"},"body":{"type":"object","nullable":true},"level":{"type":"string"},"isRead":{"type":"boolean"},"readTime":{"type":"object","nullable":true},"linkUrl":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","userId","title","body","level","isRead","readTime","linkUrl","creationTime"]},"NotificationListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/NotificationDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"},"unreadCount":{"type":"number","description":"Count of unread notifications visible to the caller."}},"required":["items","meta","unreadCount"]},"CreateNotificationDto":{"type":"object","properties":{"title":{"type":"string"},"body":{"type":"string"},"level":{"type":"string","enum":["info","success","warning","error"],"default":"info"},"userId":{"type":"string","description":"Target user id (bigint). Omit for a tenant-wide notice."},"linkUrl":{"type":"string"}},"required":["title"]},"AccountSubscriptionDto":{"type":"object","properties":{"editionName":{"type":"object","nullable":true},"editionDisplayName":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"since":{"format":"date-time","type":"string","description":"Tenant creation time (the \"member since\" date)."},"subscriptionStartedAt":{"type":"string","nullable":true,"description":"Stripe subscription start_date (when the paid subscription began)."},"trialEndsAt":{"type":"string","nullable":true},"trialDaysRemaining":{"type":"number","nullable":true},"subscriptionStatus":{"type":"string"},"subscriptionCurrentPeriodEnd":{"type":"string","nullable":true},"requiresSubscription":{"type":"boolean"},"canAccessApp":{"type":"boolean"}},"required":["editionName","editionDisplayName","isActive","since","subscriptionStartedAt","trialEndsAt","trialDaysRemaining","subscriptionStatus","subscriptionCurrentPeriodEnd","requiresSubscription","canAccessApp"]},"AccountProfileDto":{"type":"object","properties":{"tenantId":{"type":"number"},"name":{"type":"string"},"legalName":{"type":"object","nullable":true},"contactEmail":{"type":"object","nullable":true},"contactPhone":{"type":"object","nullable":true},"website":{"type":"object","nullable":true},"billingEmail":{"type":"object","nullable":true},"addressLine1":{"type":"object","nullable":true},"addressLine2":{"type":"object","nullable":true},"city":{"type":"object","nullable":true},"stateCode":{"type":"object","nullable":true},"postalCode":{"type":"object","nullable":true},"country":{"type":"object","nullable":true},"fein":{"type":"string","nullable":true,"description":"Federal Employer Identification Number (LEDES LAW_FIRM_ID)."},"subscription":{"$ref":"#/components/schemas/AccountSubscriptionDto"}},"required":["tenantId","name","legalName","contactEmail","contactPhone","website","billingEmail","addressLine1","addressLine2","city","stateCode","postalCode","country","fein","subscription"]},"UpdateAccountProfileDto":{"type":"object","properties":{"name":{"type":"string","description":"Display/tenant name."},"legalName":{"type":"string","nullable":true},"contactEmail":{"type":"string","nullable":true},"contactPhone":{"type":"string","nullable":true},"addressLine1":{"type":"string","nullable":true},"addressLine2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"stateCode":{"type":"string","nullable":true},"postalCode":{"type":"string","nullable":true},"fein":{"type":"string","nullable":true,"maxLength":10,"description":"Federal Employer Identification Number, printed as LEDES LAW_FIRM_ID (legacy CustomerProfile.FEIN). Digits and an optional dash, up to 10 characters. Empty or null clears it."}}},"SubscriptionPlanDto":{"type":"object","properties":{"id":{"type":"number"},"displayName":{"type":"string"},"name":{"type":"string"},"priceId":{"type":"string"}},"required":["id","displayName","name","priceId"]},"SubscriptionSummaryDto":{"type":"object","properties":{"editionName":{"type":"object","nullable":true},"editionDisplayName":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"since":{"format":"date-time","type":"string","description":"Tenant creation time (the \"member since\" date)."},"subscriptionStartedAt":{"type":"string","nullable":true,"description":"Stripe subscription start_date (when the paid subscription began)."},"trialEndsAt":{"type":"string","nullable":true},"trialDaysRemaining":{"type":"number","nullable":true},"subscriptionStatus":{"type":"string"},"subscriptionCurrentPeriodEnd":{"type":"string","nullable":true},"requiresSubscription":{"type":"boolean"},"canAccessApp":{"type":"boolean"},"hasStripeCustomer":{"type":"boolean"},"plans":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionPlanDto"}}},"required":["editionName","editionDisplayName","isActive","since","subscriptionStartedAt","trialEndsAt","trialDaysRemaining","subscriptionStatus","subscriptionCurrentPeriodEnd","requiresSubscription","canAccessApp","hasStripeCustomer","plans"]},"BillingContactDto":{"type":"object","properties":{"hasStripeCustomer":{"type":"boolean"},"name":{"type":"object","nullable":true},"billingEmail":{"type":"object","nullable":true},"phone":{"type":"object","nullable":true},"addressLine1":{"type":"object","nullable":true},"addressLine2":{"type":"object","nullable":true},"city":{"type":"object","nullable":true},"state":{"type":"object","nullable":true},"postalCode":{"type":"object","nullable":true},"country":{"type":"object","nullable":true}},"required":["hasStripeCustomer","name","billingEmail","phone","addressLine1","addressLine2","city","state","postalCode","country"]},"SubscriptionChargeDto":{"type":"object","properties":{"id":{"type":"string","description":"Stripe object id (in_… or cn_…)."},"kind":{"type":"string","description":"invoice | credit_note"},"date":{"format":"date-time","type":"string"},"description":{"type":"string"},"amountCents":{"type":"number","description":"Signed amount in the smallest currency unit (cents). Credits are negative."},"currency":{"type":"string"},"status":{"type":"string"},"hostedInvoiceUrl":{"type":"string","nullable":true}},"required":["id","kind","date","description","amountCents","currency","status","hostedInvoiceUrl"]},"SubscriptionChargesResponseDto":{"type":"object","properties":{"hasStripeCustomer":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionChargeDto"}}},"required":["hasStripeCustomer","items"]},"SubscriptionPlansResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionPlanDto"}}},"required":["items"]},"CreateCheckoutSessionDto":{"type":"object","properties":{"editionId":{"type":"number"},"successUrl":{"type":"string"},"cancelUrl":{"type":"string"}},"required":["editionId","successUrl","cancelUrl"]},"CheckoutSessionResponseDto":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"CreatePortalSessionDto":{"type":"object","properties":{"returnUrl":{"type":"string"}},"required":["returnUrl"]},"PortalSessionResponseDto":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"TenantDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"firstName":{"type":"string","nullable":true,"description":"First name of the first active tenant user, when available."},"trialStartDate":{"type":"string","nullable":true},"trialEndDate":{"type":"string","nullable":true},"subscriptionStatus":{"type":"string","description":"SaaS subscription status (none | active | past_due | canceled | unpaid | incomplete)."},"stripeCustomerId":{"type":"string","nullable":true,"description":"Stripe customer id (cus_…) when linked."},"isActive":{"type":"boolean"},"editionId":{"type":"object","nullable":true},"editionName":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"userCount":{"type":"number","description":"Non-deleted users in the tenant."}},"required":["id","name","firstName","trialStartDate","trialEndDate","subscriptionStatus","stripeCustomerId","isActive","editionId","editionName","creationTime","userCount"]},"TenantListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TenantDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateTenantDto":{"type":"object","properties":{"name":{"type":"string"},"editionId":{"type":"object","nullable":true},"isActive":{"type":"boolean","default":true},"contactEmail":{"type":"string","description":"Legacy contact email; when adminEmail is omitted, used for the admin user and welcome email."},"adminEmail":{"type":"string","description":"Admin user email. Provisions an Admin identity/membership on create."},"adminPassword":{"type":"string","description":"Admin password. Required unless setRandomPassword is true."},"setRandomPassword":{"type":"boolean","default":true,"description":"When true (default if no adminPassword), generate a random admin password."},"shouldChangePasswordOnNextLogin":{"type":"boolean","default":false},"sendWelcomeEmail":{"type":"boolean","default":true,"description":"Send the welcome-email template to the admin/contact address after create."}},"required":["name"]},"UpdateTenantDto":{"type":"object","properties":{"name":{"type":"string"},"editionId":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"trialStartDate":{"type":"object","nullable":true},"trialEndDate":{"type":"object","nullable":true},"subscriptionStatus":{"type":"string","description":"SaaS subscription status: none | active | past_due | canceled | unpaid | incomplete. Prefer Sync from Stripe when a customer id is set."},"stripeCustomerId":{"type":"object","nullable":true,"description":"Stripe customer id (cus_…). Paste from Dashboard for migrated firms, then Sync."}}},"HostTenantUserDto":{"type":"object","properties":{"id":{"type":"string"},"firstName":{"type":"string"},"email":{"type":"string"},"userName":{"type":"string"}},"required":["id","firstName","email","userName"]},"SelectTenantUserDto":{"type":"object","properties":{"userId":{"type":"string","description":"Membership id of the user to open in the selected tenant."}},"required":["userId"]},"TenantFeatureNodeDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"},"parentName":{"type":"object","nullable":true},"value":{"type":"string"},"isEnabled":{"type":"boolean"},"children":{"type":"array","items":{"$ref":"#/components/schemas/TenantFeatureNodeDto"}}},"required":["name","displayName","parentName","value","isEnabled","children"]},"TenantFeaturesDto":{"type":"object","properties":{"features":{"type":"array","items":{"$ref":"#/components/schemas/TenantFeatureNodeDto"}}},"required":["features"]},"TenantFeatureValueDto":{"type":"object","properties":{"name":{"type":"string"},"value":{"type":"string"}},"required":["name","value"]},"UpdateTenantFeaturesDto":{"type":"object","properties":{"values":{"type":"array","items":{"$ref":"#/components/schemas/TenantFeatureValueDto"}}},"required":["values"]},"EditionDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"displayName":{"type":"string"},"creationTime":{"format":"date-time","type":"string"},"tenantCount":{"type":"number","description":"Tenants currently assigned to this edition."}},"required":["id","name","displayName","creationTime","tenantCount"]},"CreateEditionDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"}},"required":["name","displayName"]},"UpdateEditionDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"}}},"UpdateEditionFeaturesDto":{"type":"object","properties":{"values":{"type":"array","items":{"$ref":"#/components/schemas/TenantFeatureValueDto"}}},"required":["values"]},"HostAdministrationAuditLogDto":{"type":"object","properties":{"id":{"type":"string"},"tenantName":{"type":"object","nullable":true},"actorLabel":{"type":"object","nullable":true},"action":{"type":"string"},"resource":{"type":"object","nullable":true},"path":{"type":"string"},"statusCode":{"type":"object","nullable":true},"durationMs":{"type":"object","nullable":true},"ipAddress":{"type":"object","nullable":true},"location":{"type":"object","nullable":true},"browserInfo":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","tenantName","actorLabel","action","resource","path","statusCode","durationMs","ipAddress","location","browserInfo","creationTime"]},"HostAdministrationAuditLogListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/HostAdministrationAuditLogDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"HostAdministrationRoleDetailDto":{"type":"object","properties":{"id":{"type":"number"},"tenantId":{"type":"number"},"tenantName":{"type":"string"},"name":{"type":"string"},"isStatic":{"type":"boolean"},"permissionCount":{"type":"number"},"creationTime":{"format":"date-time","type":"string"},"permissionIds":{"type":"array","items":{"type":"number"}}},"required":["id","tenantId","tenantName","name","isStatic","permissionCount","creationTime","permissionIds"]},"HostAdministrationUserDetailDto":{"type":"object","properties":{"id":{"type":"string"},"tenantId":{"type":"number"},"tenantName":{"type":"string"},"userName":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"object","nullable":true},"lastName":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"roleNames":{"type":"array","items":{"type":"string"}},"creationTime":{"format":"date-time","type":"string"},"roleIds":{"type":"array","items":{"type":"number"}}},"required":["id","tenantId","tenantName","userName","email","firstName","lastName","isActive","roleNames","creationTime","roleIds"]},"HostAdministrationLanguageDetailDto":{"type":"object","properties":{"id":{"type":"number"},"tenantId":{"type":"number"},"tenantName":{"type":"string"},"name":{"type":"string"},"displayName":{"type":"string"},"isDefault":{"type":"boolean"},"isDisabled":{"type":"boolean"},"creationTime":{"format":"date-time","type":"string"},"icon":{"type":"object","nullable":true}},"required":["id","tenantId","tenantName","name","displayName","isDefault","isDisabled","creationTime","icon"]},"UpdateLanguageDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"},"icon":{"type":"string"},"isDisabled":{"type":"boolean"},"isDefault":{"type":"boolean"}}},"LanguageTextDto":{"type":"object","properties":{"id":{"type":"number"},"languageId":{"type":"number"},"source":{"type":"object","nullable":true},"key":{"type":"string"},"value":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","languageId","source","key","value","creationTime"]},"HostAdministrationLanguageTextListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LanguageTextDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"UpdateLanguageTextDto":{"type":"object","properties":{"source":{"type":"string"},"key":{"type":"string"},"value":{"type":"string"}}},"HostAdministrationAuditLogDetailDto":{"type":"object","properties":{"id":{"type":"string"},"tenantId":{"type":"number"},"tenantName":{"type":"string"},"actorUserId":{"type":"object","nullable":true},"actorType":{"type":"string"},"actorLabel":{"type":"object","nullable":true},"action":{"type":"string"},"resource":{"type":"object","nullable":true},"path":{"type":"string"},"entityId":{"type":"object","nullable":true},"statusCode":{"type":"object","nullable":true},"requestId":{"type":"object","nullable":true},"durationMs":{"type":"object","nullable":true},"ipAddress":{"type":"object","nullable":true},"location":{"type":"object","nullable":true},"browserInfo":{"type":"object","nullable":true},"userAgent":{"type":"object","nullable":true},"clientName":{"type":"object","nullable":true},"parameters":{"type":"object","nullable":true,"additionalProperties":true},"summary":{"nullable":true,"description":"Human-readable summary with resolved entity names.","type":"object","allOf":[{"$ref":"#/components/schemas/AuditSummaryDto"}]},"exception":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"}},"required":["id","tenantId","tenantName","actorUserId","actorType","actorLabel","action","resource","path","entityId","statusCode","requestId","durationMs","ipAddress","location","browserInfo","userAgent","clientName","parameters","summary","exception","creationTime"]},"WelcomeEmailDto":{"type":"object","properties":{"subject":{"type":"string","description":"Email subject; supports {{tenantName}} placeholders."},"body":{"type":"string","description":"Email body; supports {{tenantName}} and {{loginUrl}} placeholders."}},"required":["subject","body"]},"UpdateWelcomeEmailDto":{"type":"object","properties":{"subject":{"type":"string"},"body":{"type":"string"}},"required":["subject","body"]},"StripePlanDto":{"type":"object","properties":{"displayName":{"type":"string","description":"Product name (and amount/interval when available) for display."},"priceId":{"type":"string","description":"Stripe Price id stored as Edition.name."},"productId":{"type":"string","nullable":true}},"required":["displayName","priceId","productId"]},"HostSettingDto":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"object","nullable":true},"lastModificationTime":{"type":"object","nullable":true}},"required":["key","value","lastModificationTime"]},"HostSettingInputDto":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"object","nullable":true}},"required":["key","value"]},"UpdateHostSettingsDto":{"type":"object","properties":{"settings":{"type":"array","items":{"$ref":"#/components/schemas/HostSettingInputDto"}}},"required":["settings"]},"QueueStatsDto":{"type":"object","properties":{"name":{"type":"string"},"waiting":{"type":"number"},"active":{"type":"number"},"completed":{"type":"number"},"failed":{"type":"number"},"delayed":{"type":"number"}},"required":["name","waiting","active","completed","failed","delayed"]},"MaintenanceStatusDto":{"type":"object","properties":{"appVersion":{"type":"string"},"nodeVersion":{"type":"string"},"uptimeSeconds":{"type":"number"},"queues":{"type":"array","items":{"$ref":"#/components/schemas/QueueStatsDto"}}},"required":["appVersion","nodeVersion","uptimeSeconds","queues"]},"ContactOrphanSummaryDto":{"type":"object","properties":{"linkType":{"type":"string"},"contactKind":{"type":"string","enum":["person","organization"]},"count":{"type":"number"}},"required":["linkType","contactKind","count"]},"ContactOrphanRowDto":{"type":"object","properties":{"tenantId":{"type":"number"},"tenantName":{"type":"string"},"linkType":{"type":"string","description":"Source table: participant, victim, officer, prosecutor, bondsman, rollCallLocation, lien, doctor, provider, insurance, subrogor, workHistory or billingEntity."},"linkId":{"type":"number"},"caseId":{"type":"number","nullable":true,"description":"Null for billing entities."},"caseNumber":{"type":"string","nullable":true},"contactKind":{"type":"string","enum":["person","organization"]},"contactId":{"type":"string","description":"Person ids are bigints, sent as strings."},"contactName":{"type":"string"},"contactDeletedAt":{"format":"date-time","type":"string","nullable":true}},"required":["tenantId","tenantName","linkType","linkId","caseId","caseNumber","contactKind","contactId","contactName","contactDeletedAt"]},"ContactOrphanReportDto":{"type":"object","properties":{"total":{"type":"number","description":"Total orphaned links (not capped by limit)."},"summary":{"type":"array","items":{"$ref":"#/components/schemas/ContactOrphanSummaryDto"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/ContactOrphanRowDto"}}},"required":["total","summary","rows"]},"FeatureRequestDto":{"type":"object","properties":{"id":{"type":"number"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["requested","under_review","planned","in_progress","shipped","closed"]},"source":{"type":"string","description":"community (user-submitted) or team (published by CaseWizard)."},"score":{"type":"number","description":"Net score (upvotes minus downvotes)."},"upvotes":{"type":"number"},"downvotes":{"type":"number"},"myVote":{"type":"number","enum":[1,0,-1],"description":"The caller's own vote."},"commentCount":{"type":"number","description":"Visible (not deleted) comments, excluding status events."},"isFollowing":{"type":"boolean","description":"Whether the calling user follows this request."},"closedReason":{"type":"string","enum":["declined","duplicate","completed"],"nullable":true},"duplicateOfId":{"type":"object","nullable":true,"description":"The request this one duplicates, when closed as duplicate."},"statusNote":{"type":"object","nullable":true,"description":"Staff note explaining the current status."},"isLocked":{"type":"boolean","description":"When true, new comments are disabled."},"createdByUserId":{"type":"object","nullable":true},"createdByName":{"type":"object","nullable":true},"creationTime":{"format":"date-time","type":"string"},"lastActivityAt":{"format":"date-time","type":"string"}},"required":["id","title","description","status","source","score","upvotes","downvotes","myVote","commentCount","isFollowing","closedReason","duplicateOfId","statusNote","isLocked","createdByUserId","createdByName","creationTime","lastActivityAt"]},"FeatureRequestStatusCountDto":{"type":"object","properties":{"status":{"type":"string","enum":["requested","under_review","planned","in_progress","shipped","closed"]},"count":{"type":"number"}},"required":["status","count"]},"HostFeatureRequestListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FeatureRequestDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"},"statusCounts":{"description":"Request counts per status across the whole board, ignoring search and paging.","type":"array","items":{"$ref":"#/components/schemas/FeatureRequestStatusCountDto"}}},"required":["items","meta","statusCounts"]},"UpdateHostFeatureRequestDto":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["requested","under_review","planned","in_progress","shipped","closed"]},"closedReason":{"type":"string","enum":["declined","duplicate","completed"],"description":"Required when the resulting status is closed."},"duplicateOfId":{"type":"number","description":"The request this one duplicates (closedReason = duplicate)."},"statusNote":{"type":"string","description":"Note shown to everyone and included in follower emails. Empty clears it."},"isLocked":{"type":"boolean","description":"Lock or unlock new comments."}}},"FeatureRequestFollowerCountDto":{"type":"object","properties":{"count":{"type":"number"}},"required":["count"]},"FeatureRequestCommentDto":{"type":"object","properties":{"id":{"type":"number"},"parentId":{"type":"object","nullable":true},"kind":{"type":"string","enum":["comment","status_change"]},"body":{"type":"string","description":"Empty when the comment was deleted."},"authorName":{"type":"object","nullable":true},"isStaff":{"type":"boolean","description":"Posted by CaseWizard staff."},"isMine":{"type":"boolean","description":"Posted by the calling user."},"isDeleted":{"type":"boolean"},"creationTime":{"format":"date-time","type":"string"},"editedTime":{"type":"object","nullable":true},"metadata":{"type":"object","nullable":true,"description":"Status events: { from, to, closedReason?, duplicateOfId? }.","additionalProperties":true},"replies":{"description":"Replies, oldest first.","type":"array","items":{"$ref":"#/components/schemas/FeatureRequestCommentDto"}}},"required":["id","parentId","kind","body","authorName","isStaff","isMine","isDeleted","creationTime","editedTime","metadata","replies"]},"FeatureRequestCommentListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FeatureRequestCommentDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateFeatureRequestCommentDto":{"type":"object","properties":{"body":{"type":"string","description":"Plain text.","maxLength":4000},"parentId":{"type":"number","description":"Reply to this comment (replies nest one level only)."}},"required":["body"]},"FeatureRequestListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/FeatureRequestDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateFeatureRequestDto":{"type":"object","properties":{"title":{"type":"string","example":"Two-way Outlook calendar sync"},"description":{"type":"string"}},"required":["title"]},"VoteFeatureRequestDto":{"type":"object","properties":{"value":{"type":"number","enum":[1,0,-1],"description":"Your vote: 1 = up, -1 = down, 0 = clear."}},"required":["value"]},"UpdateFeatureRequestCommentDto":{"type":"object","properties":{"body":{"type":"string","maxLength":4000}},"required":["body"]},"FollowStateDto":{"type":"object","properties":{"isFollowing":{"type":"boolean"}},"required":["isFollowing"]},"UnsubscribeDto":{"type":"object","properties":{"token":{"type":"string","description":"The signed token from a community email footer."}},"required":["token"]},"UnsubscribeResultDto":{"type":"object","properties":{"scope":{"type":"string","enum":["request","all"]},"featureRequestId":{"type":"object","nullable":true},"featureRequestTitle":{"type":"object","nullable":true}},"required":["scope","featureRequestId","featureRequestTitle"]},"LanguageDto":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"displayName":{"type":"string"},"icon":{"type":"object","nullable":true},"isDisabled":{"type":"boolean"},"isDefault":{"type":"boolean"},"creationTime":{"format":"date-time","type":"string"}},"required":["id","name","displayName","icon","isDisabled","isDefault","creationTime"]},"LanguageListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LanguageDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateLanguageDto":{"type":"object","properties":{"name":{"type":"string","description":"Culture code, e.g. \"en\" or \"en-US\"."},"displayName":{"type":"string","description":"Human-readable language name."},"icon":{"type":"string","description":"Optional flag/icon reference."},"isDisabled":{"type":"boolean","default":false},"isDefault":{"type":"boolean","default":false}},"required":["name","displayName"]},"LanguageTextListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/LanguageTextDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateLanguageTextDto":{"type":"object","properties":{"source":{"type":"string","description":"Logical source/namespace, e.g. \"CaseWizard\"."},"key":{"type":"string","description":"Resource key."},"value":{"type":"string","description":"Translated value."}},"required":["key"]},"OrganizationUnitDto":{"type":"object","properties":{"id":{"type":"number"},"parentId":{"type":"object","nullable":true},"code":{"type":"object","nullable":true},"displayName":{"type":"string"},"creationTime":{"format":"date-time","type":"string"}},"required":["id","parentId","code","displayName","creationTime"]},"OrganizationUnitListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/OrganizationUnitDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateOrganizationUnitDto":{"type":"object","properties":{"displayName":{"type":"string","description":"Display name of the unit."},"parentId":{"type":"number","description":"Parent unit id (omit for a root unit)."},"code":{"type":"string","description":"Optional hierarchy code."}},"required":["displayName"]},"UpdateOrganizationUnitDto":{"type":"object","properties":{"displayName":{"type":"string"},"parentId":{"type":"number"},"code":{"type":"string"}}},"BillingCodeListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/BillingCodeDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"CreateBillingCodeDto":{"type":"object","properties":{"code":{"type":"string","description":"The billing code."},"description":{"type":"string"},"activityId":{"type":"number","description":"LEDES activity code id."},"taskId":{"type":"number","description":"LEDES task code id."}},"required":["code"]},"UpdateBillingCodeDto":{"type":"object","properties":{"code":{"type":"string"},"description":{"type":"string"},"activityId":{"type":"object","nullable":true},"taskId":{"type":"object","nullable":true}}},"ProductReleaseHighlightDto":{"type":"object","properties":{"type":{"type":"string","enum":["new","improved","fixed"],"example":"improved"},"title":{"type":"string","example":"Case search reaches every detail you can see"},"description":{"type":"string","example":"Search now covers case style, assigned staff, status, and other visible fields."}},"required":["type","title"]},"ProductReleaseRollupDto":{"type":"object","properties":{"firstVersion":{"type":"string","example":"2.0.1","description":"Oldest patch release included in this note."},"lastVersion":{"type":"string","example":"2.0.169","description":"Newest patch release included in this note."},"patchCount":{"type":"number","example":169}},"required":["firstVersion","lastVersion","patchCount"]},"ProductReleaseDto":{"type":"object","properties":{"id":{"type":"string","example":"release-2.0.1"},"version":{"type":"string","example":"2.0.1"},"title":{"type":"string","example":"Find it faster, keep moving"},"summary":{"type":"string","example":"This release makes everyday case work faster and keeps your place while you browse."},"highlights":{"type":"array","items":{"$ref":"#/components/schemas/ProductReleaseHighlightDto"}},"publishedAt":{"type":"string","example":"2026-08-12T22:00:00.000Z"},"source":{"type":"string","enum":["web","api","word"],"example":"web"},"commitSha":{"type":"string","example":"97f3111fa31444782de0ed590e6d3b9de1c0b799"},"rollup":{"description":"Present on a weekly \"What's new\" release (X.Y.0): the patches it consolidates.","allOf":[{"$ref":"#/components/schemas/ProductReleaseRollupDto"}]}},"required":["id","version","title","summary","highlights","publishedAt","source","commitSha"]},"ProductReleaseFeedDto":{"type":"object","properties":{"currentVersion":{"type":"string","example":"2.1.4","description":"The exact version deployed, patches included."},"items":{"description":"The announced \"What's new\" releases (X.Y.0), newest first.","type":"array","items":{"$ref":"#/components/schemas/ProductReleaseDto"}},"patches":{"description":"Every patch release still retained, newest first. Not announced individually.","type":"array","items":{"$ref":"#/components/schemas/ProductReleaseDto"}}},"required":["currentVersion","items","patches"]},"IngestRequestDto":{"type":"object","properties":{"runId":{"type":"string","description":"Migration run id (uuid) that owns the rows produced."},"entityName":{"type":"string","description":"Logical entity name (also the crosswalk key), e.g. \"cases\"."},"model":{"type":"string","description":"Prisma model name, e.g. \"Case\" (matches schema.prisma)."},"tenantId":{"type":"number","nullable":true,"description":"Tenant id for tenant-scoped rows; null for host-global entities (tenants, editions)."},"naturalKey":{"description":"Natural-key field names on the target for ON CONFLICT resolution, e.g. [\"tenantId\",\"userName\"].","type":"array","items":{"type":"string"}},"records":{"type":"array","items":{"type":"object","additionalProperties":true},"maxItems":500,"description":"Pre-transformed records (camelCase Prisma fields)."}},"required":["runId","entityName","model","tenantId","naturalKey","records"]},"IngestResultDto":{"type":"object","properties":{"legacyId":{"type":"object","nullable":true,"description":"The record's legacy id, echoed back for crosswalk keying."},"id":{"type":"string","description":"Resulting primary key (server-assigned or pinned). Empty on a per-record error."},"inserted":{"type":"boolean","description":"True when a new row was added; false for a natural-key conflict (idempotent re-load)."},"error":{"type":"object","nullable":true,"description":"Per-record data error (e.g. FK/constraint violation); the client quarantines just this row."}},"required":["legacyId","id","inserted"]},"IngestResponseDto":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/IngestResultDto"}}},"required":["results"]},"StartRunDto":{"type":"object","properties":{"runId":{"type":"string"},"kind":{"type":"string","enum":["run","dry-run"]}},"required":["runId","kind"]},"LatestRunDto":{"type":"object","properties":{"runId":{"type":"object","nullable":true,"description":"Id of the most recent real (mode = \"run\") migration, or null."}},"required":["runId"]},"EntityStatsReadRowDto":{"type":"object","properties":{"entityName":{"type":"string"},"source":{"type":"number"},"loaded":{"type":"number"},"quarantined":{"type":"number"},"skipped":{"type":"number"}},"required":["entityName","source","loaded","quarantined","skipped"]},"EntityStatsReadResponseDto":{"type":"object","properties":{"stats":{"type":"array","items":{"$ref":"#/components/schemas/EntityStatsReadRowDto"}}},"required":["stats"]},"EntityStatsRowDto":{"type":"object","properties":{"entityName":{"type":"string"},"tenantId":{"type":"number","nullable":true,"description":"Tenant id; null = host-global."},"source":{"type":"number"},"loaded":{"type":"number"},"quarantined":{"type":"number"},"skipped":{"type":"number"}},"required":["entityName","tenantId","source","loaded","quarantined","skipped"]},"EntityStatsBatchDto":{"type":"object","properties":{"runId":{"type":"string"},"stats":{"maxItems":500,"type":"array","items":{"$ref":"#/components/schemas/EntityStatsRowDto"}}},"required":["runId","stats"]},"OkCountDto":{"type":"object","properties":{"count":{"type":"number","description":"Number of rows written/affected."}},"required":["count"]},"CrosswalkRowDto":{"type":"object","properties":{"entityName":{"type":"string"},"legacyId":{"type":"string"},"newId":{"type":"string"},"tenantId":{"type":"number","nullable":true},"model":{"type":"string","description":"Prisma model name, recorded so rollback can delete the right table. Optional."}},"required":["entityName","legacyId","newId","tenantId"]},"CrosswalkBatchDto":{"type":"object","properties":{"runId":{"type":"string","description":"Run id the crosswalk rows belong to."},"rows":{"maxItems":500,"type":"array","items":{"$ref":"#/components/schemas/CrosswalkRowDto"}}},"required":["runId","rows"]},"CrosswalkResponseDto":{"type":"object","properties":{"rows":{"type":"array","items":{"$ref":"#/components/schemas/CrosswalkRowDto"}}},"required":["rows"]},"QuarantineRowDto":{"type":"object","properties":{"entityName":{"type":"string"},"legacyId":{"type":"object","nullable":true},"tenantId":{"type":"number","nullable":true},"reasonCode":{"type":"string","description":"Enumerated reason code, e.g. CONSTRAINT_VIOLATION."},"detail":{"type":"object","nullable":true},"sourceRow":{"type":"object","additionalProperties":true,"description":"The full source row."}},"required":["entityName","legacyId","tenantId","reasonCode","detail","sourceRow"]},"QuarantineBatchDto":{"type":"object","properties":{"runId":{"type":"string"},"rows":{"maxItems":500,"type":"array","items":{"$ref":"#/components/schemas/QuarantineRowDto"}}},"required":["runId","rows"]},"LookupRowsDto":{"type":"object","properties":{"entityName":{"type":"string"},"keyField":{"type":"string","enum":["legacyId","name","code"]},"rows":{"type":"array","items":{"type":"object","additionalProperties":true},"description":"Rows: { id, legacyId }, { id, name } or { id, code } depending on keyField."}},"required":["entityName","keyField","rows"]},"LookupsResponseDto":{"type":"object","properties":{"lookups":{"type":"array","items":{"$ref":"#/components/schemas/LookupRowsDto"}}},"required":["lookups"]},"CountResponseDto":{"type":"object","properties":{"count":{"type":"number"}},"required":["count"]},"SumResponseDto":{"type":"object","properties":{"sum":{"type":"string","description":"Decimal string (scale preserved)."}},"required":["sum"]},"GrantVerdictDto":{"type":"object","properties":{"table":{"type":"string"},"rls":{"type":"boolean","description":"Whether row-level security is enabled on the table."},"missing":{"description":"Required privileges casewizard_app is missing (empty when satisfied).","type":"array","items":{"type":"string"}},"ok":{"type":"boolean"}},"required":["table","rls","missing","ok"]},"GrantsResponseDto":{"type":"object","properties":{"ok":{"type":"boolean"},"verdicts":{"type":"array","items":{"$ref":"#/components/schemas/GrantVerdictDto"}}},"required":["ok","verdicts"]},"RepairGrantsResponseDto":{"type":"object","properties":{"ok":{"type":"boolean"},"dmlTables":{"description":"RLS-enabled tables that (re)received DML.","type":"array","items":{"type":"string"}},"readTables":{"type":"number","description":"Total public tables that (re)received SELECT."}},"required":["ok","dmlTables","readTables"]},"PermissionCatalogNodeDto":{"type":"object","properties":{"name":{"type":"string"},"displayName":{"type":"string"},"parentName":{"type":"string","nullable":true}},"required":["name","displayName","parentName"]},"PrepareDto":{"type":"object","properties":{"permissions":{"deprecated":true,"description":"Ignored. Legacy Pages.* permission catalogue, retired in favour of function permissions (ADR-0011). Accepted only so older casewizard-migrate clients are not rejected.","type":"array","items":{"$ref":"#/components/schemas/PermissionCatalogNodeDto"}}}},"PrepareResponseDto":{"type":"object","properties":{"migrationsApplied":{"type":"number","description":"Number of Prisma migrations applied during this prepare call."},"seeded":{"type":"boolean","description":"True when the baseline seed completed."},"grantsOk":{"type":"boolean","description":"True when casewizard_app grants passed verification after repair."}},"required":["migrationsApplied","seeded","grantsOk"]},"IdentityBackfillResponseDto":{"type":"object","properties":{"identities":{"type":"number","description":"Total identities present after the backfill."},"linkedUsers":{"type":"number","description":"Users linked to an identity (identity_id NOT NULL)."},"unlinkedUsers":{"type":"number","description":"Users still unlinked (null/blank email — no identity derivable)."}},"required":["identities","linkedUsers","unlinkedUsers"]},"BillingSettingsBackfillResponseDto":{"type":"object","properties":{"tenantsUpdated":{"type":"number","description":"BillingSetting rows that have next_invoice_number set after recovery from MAX(invoice_number)+1."}},"required":["tenantsUpdated"]},"TenantFirmDetailsDto":{"type":"object","properties":{"tenantId":{"type":"number","description":"Target tenant id (equals the legacy AbpTenants.Id)."},"fein":{"type":"string","nullable":true,"maxLength":10},"legalName":{"type":"string","nullable":true,"maxLength":255},"addressLine1":{"type":"string","nullable":true,"maxLength":255},"addressLine2":{"type":"string","nullable":true,"maxLength":255},"city":{"type":"string","nullable":true,"maxLength":100},"stateCode":{"type":"string","nullable":true,"maxLength":64},"postalCode":{"type":"string","nullable":true,"maxLength":32}},"required":["tenantId"]},"TenantFirmDetailsBatchDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/TenantFirmDetailsDto"}}},"required":["items"]},"TenantFirmDetailsResponseDto":{"type":"object","properties":{"tenantsUpdated":{"type":"number","description":"Tenants that had at least one blank field filled."},"fieldsSet":{"type":"number","description":"Total tenant columns filled across all tenants."}},"required":["tenantsUpdated","fieldsSet"]},"SyncSequencesResponseDto":{"type":"object","properties":{"ok":{"type":"boolean","description":"True when every public serial/identity sequence was advanced."}},"required":["ok"]},"CascadeDeletedCasesResponseDto":{"type":"object","properties":{"rowsDeleted":{"type":"number","description":"Case-owned rows (events, participants, documents, ...) soft-deleted because their case is deleted."}},"required":["rowsDeleted"]},"RerateFixedFeeTimeResponseDto":{"type":"object","properties":{"rowsUpdated":{"type":"number","description":"Not-yet-invoiced time entries on Fixed Fee cases re-rated to $0."}},"required":["rowsUpdated"]},"ClearTenantDto":{"type":"object","properties":{"tenantIds":{"description":"Tenant ids to wipe (positive integers).","type":"array","items":{"type":"number"}}},"required":["tenantIds"]},"ClearTenantResponseDto":{"type":"object","properties":{"removed":{"type":"number","description":"Total model rows removed across the requested tenants."}},"required":["removed"]},"RollbackDto":{"type":"object","properties":{"runId":{"type":"string"}},"required":["runId"]},"RollbackResponseDto":{"type":"object","properties":{"removed":{"type":"number","description":"Total model rows deleted for the run."}},"required":["removed"]},"MigrationResetPasswordDto":{"type":"object","properties":{"tenantIds":{"description":"Restrict to these tenant ids (positive integers).","type":"array","items":{"type":"number"}},"identifier":{"type":"string","description":"Match users whose userName OR email equals this value."},"password":{"type":"string","description":"Plaintext password to set (argon2-hashed)."}},"required":["password"]},"ResetPasswordResponseDto":{"type":"object","properties":{"count":{"type":"number","description":"Number of users updated."}},"required":["count"]},"LookupUserRowDto":{"type":"object","properties":{"tenantId":{"type":"number","nullable":true},"userName":{"type":"string","description":"Login matches on userName, not email."},"email":{"type":"string"},"isActive":{"type":"boolean"},"isDeleted":{"type":"boolean"},"hashKind":{"type":"string","enum":["argon2","aspnet","other","empty"]}},"required":["tenantId","userName","email","isActive","isDeleted","hashKind"]},"LookupUsersResponseDto":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/LookupUserRowDto"}}},"required":["users"]},"HostAdministrationUserDto":{"type":"object","properties":{"id":{"type":"string"},"tenantId":{"type":"number"},"tenantName":{"type":"string"},"userName":{"type":"string"},"email":{"type":"string"},"firstName":{"type":"object","nullable":true},"lastName":{"type":"object","nullable":true},"isActive":{"type":"boolean"},"roleNames":{"type":"array","items":{"type":"string"}},"creationTime":{"format":"date-time","type":"string"}},"required":["id","tenantId","tenantName","userName","email","firstName","lastName","isActive","roleNames","creationTime"]},"HostAdministrationUserListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/HostAdministrationUserDto"}},"meta":{"$ref":"#/components/schemas/PageMetaDto"}},"required":["items","meta"]},"PlatformSetUserActiveDto":{"type":"object","properties":{"isActive":{"type":"boolean","description":"Enable or disable the user."}},"required":["isActive"]}}}}