{"openapi":"3.0.0","info":{"version":"2026.4.0","title":"Quilia API","description":"\nThe Quilia API lets you manage cases, clients, messages, and more from your own applications.\n\n## Looking to connect an AI assistant?\n\nIf you want to point Claude, Cursor, Claude Code, or another MCP-compatible AI assistant at your firm, you do not need this reference. There is a one-click sign-in flow at [https://mcp.quilia.dev/](https://mcp.quilia.dev/) and a step-by-step walkthrough at **[quilia.com/support/firms/connect-ai-assistant](https://www.quilia.com/support/firms/connect-ai-assistant/)**. No API key required.\n\nThis API reference is for developers building their own integration against Quilia using an Unkey-issued API key.\n\n## REST API\n\nAll endpoints below are available at `https://api.quilia.dev/v2`.\n\n**Authentication:**\nInclude your API key in the `Authorization` header:\n```\ncurl -X GET https://api.quilia.dev/v2/cases \\\n  -H \"Authorization: Bearer your-api-key\"\n```\n\nNeed an API key? Create one at [portal.quilia.com/settings/integrations/api](https://portal.quilia.com/settings/integrations/api).\n\n## Markdown reference for AI tools\n\nNeed the full API reference as markdown for AI tools that don't support MCP?\n\n**[Download as Markdown →](/v2/llms.txt)**\n\n## Changelog\n\nSee the [API Changelog](https://github.com/quilia/portal/blob/development/apps/functions/CHANGELOG.md) for version history, breaking changes, and deprecations.\n","contact":{"email":"support@quilia.com","url":"https://www.quilia.com"}},"tags":[{"name":"appointments","description":"Appointment related endpoints.","x-displayName":"Appointments"},{"name":"audiences","description":"Who a message goes to. Audiences are named, reusable conditions resolved live at send time; picked lists are fixed client lists for cases such as an automation for one person.","x-displayName":"Audiences"},{"name":"automations","description":"Standing rules that turn a date into a message: an audience, a trigger date, an offset and what to say.","x-displayName":"Automations"},{"name":"auth","description":"Authentication related endpoints.","x-displayName":"Authentication"},{"name":"cases","description":"Case related endpoints.","x-displayName":"Cases"},{"name":"case-types","description":"The case types a firm uses, and the per-type options that follow from them.","x-displayName":"Case Types"},{"name":"clients","description":"Client related endpoints.","x-displayName":"Clients"},{"name":"contacts","description":"Contacts related endpoints.","x-displayName":"Contacts"},{"name":"documents","description":"Documents related endpoints.","x-displayName":"Documents"},{"name":"feed","description":"Feed related endpoints.","x-displayName":"Feed"},{"name":"messages","description":"Messages related endpoints.","x-displayName":"Messages"},{"name":"reports","description":"Report problems with Quilia itself.","x-displayName":"Reports"},{"name":"requests","description":"Requests related endpoints.","x-displayName":"Requests"},{"name":"notifications","description":"Notifications related endpoints.","x-displayName":"Notifications"},{"name":"org","description":"Organization profile and settings endpoints.","x-displayName":"Organization"},{"name":"providers","description":"Provider directory endpoints.","x-displayName":"Providers"},{"name":"search","description":"Search clients across the organization.","x-displayName":"Search"},{"name":"staff","description":"Staff member related endpoints.","x-displayName":"Staff"},{"name":"webhooks","x-displayName":"Webhooks","description":"\nWebhooks provide real-time notifications when events occur in your Quilia account. Instead of repeatedly polling our API, you can configure webhook endpoints to receive instant notifications about case updates, client changes, document uploads, and other important events.\n\n### Payload Verification\n\nEvery webhook request includes an `x-webhook-signature` header containing an HMAC-SHA256 signature. **You must verify this signature** to ensure the payload is authentic and hasn't been tampered with.\n\n#### Example Verification (Node.js)\n\n```javascript\nconst crypto = require(\"crypto\")\n\nfunction verifyWebhook(payload, signature, secret) {\nconst hash = crypto.createHmac(\"sha256\", secret).update(payload).digest(\"hex\")\n\nreturn signature === hash\n}\n\n// Example usage in Express.js\napp.post(\"/webhook\", express.raw({ type: \"application/json\" }), (req, res) => {\nconst signature = req.headers[\"x-webhook-signature\"]\nconst payload = req.body\nconst secret = process.env.WEBHOOK_SECRET\n\nif (!verifyWebhook(payload, signature, secret)) {\nreturn res.status(401).send(\"Invalid signature\")\n}\n\n// Process webhook payload\nconst data = JSON.parse(payload)\nconsole.log(\"Webhook received:\", data)\n\nres.status(200).send(\"OK\")\n})\n```\n\n### Request Headers\n\nAll webhook requests include the following headers:\n\n- `content-type: application/json`\n- `user-agent: Quilia-Webhooks/1.0`\n- `x-webhook-signature: [HMAC-SHA256 signature]`\n- `x-quilia-org-id: [Your organization ID]`\n\n### Testing and Simulation\n\nQuilia provides built-in tools to test your webhook endpoints without waiting for real events to occur.\n\n#### Webhook Simulation\n\nUse the **Simulate** feature in the Quilia dashboard to send test payloads to your webhook endpoints. This allows you to:\n\n- Test your endpoint's response to different event types\n- Verify your signature validation logic\n- Debug payload processing without triggering real events\n- Ensure your endpoint returns the expected HTTP status codes\n\n#### Testing Best Practices\n\n1. **Always verify signatures**: Test both valid and invalid signatures to ensure your verification logic is working correctly.\n\n2. **Handle duplicate events**: Webhooks may be delivered more than once. Implement idempotency using the event ID or timestamp.\n\n3. **Respond quickly**: Return a 2xx status code within 10 seconds. Perform heavy processing asynchronously.\n\n4. **Log webhook events**: Keep logs of received webhooks for debugging and monitoring.\n\n5. **Use HTTPS endpoints**: Always use secure HTTPS endpoints in production to protect sensitive data.\n\n#### Example Test Response Handler\n\n```javascript\n// Example webhook handler with proper error handling\napp.post(\"/webhook\", async (req, res) => {\n  try {\n    const signature = req.headers[\"x-webhook-signature\"]\n    const payload = req.body\n    \n    // Verify signature first\n    if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET)) {\n      console.error(\"Invalid webhook signature\")\n      return res.status(401).send(\"Unauthorized\")\n    }\n    \n    const event = JSON.parse(payload)\n    \n    // Process event asynchronously\n    processWebhookAsync(event)\n    \n    // Respond immediately\n    res.status(200).json({ received: true })\n    \n  } catch (error) {\n    console.error(\"Webhook processing error:\", error)\n    res.status(400).send(\"Bad Request\")\n  }\n})\n```\n"}],"security":[{"Bearer":[]}],"components":{"securitySchemes":{"Bearer":{"type":"http","scheme":"bearer"}},"schemas":{},"parameters":{}},"paths":{"/appointments":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["appointments"],"summary":"List appointments","description":"Retrieves a paginated list of appointments for the authenticated organization. Appointments can be filtered by user ID, case ID, or both. Returns appointment details including scheduling information, associations, notes, and status with configurable limit and offset for pagination.","parameters":[{"schema":{"type":"number","nullable":true,"default":10,"description":"The maximum number of appointments to return per page"},"required":false,"description":"The maximum number of appointments to return per page","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"The number of appointments to skip before starting to return results"},"required":false,"description":"The number of appointments to skip before starting to return results","name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter appointments by user ID. Returns only appointments assigned to this user."},"required":false,"description":"Filter appointments by user ID. Returns only appointments assigned to this user.","name":"userId","in":"query"},{"schema":{"type":"string","description":"Filter appointments by case ID. Returns only appointments associated with this case."},"required":false,"description":"Filter appointments by case ID. Returns only appointments associated with this case.","name":"caseId","in":"query"}],"responses":{"200":{"description":"List of appointments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the list operation"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the appointment"},"caseId":{"type":"string","nullable":true,"description":"The case ID associated with the appointment"},"contactId":{"type":"string","nullable":true,"description":"The contact/people ID associated with the appointment"},"userId":{"type":"string","nullable":true,"description":"The user ID associated with the appointment"},"start":{"type":"string","description":"ISO timestamp for the appointment start time"},"end":{"type":"string","nullable":true,"description":"ISO timestamp for the appointment end time"},"notes":{"type":"string","nullable":true,"description":"Additional notes or details about the appointment"},"status":{"type":"string","enum":["scheduled","confirmed","rescheduled","cancelled","canceled","released"],"description":"The current status of the appointment"},"created_at":{"type":"string","nullable":true,"description":"ISO timestamp when the appointment was created"},"updated_at":{"type":"string","nullable":true,"description":"ISO timestamp when the appointment was last updated"},"created_by":{"type":"string","nullable":true,"description":"The user ID of who created the appointment"}},"required":["id","caseId","contactId","userId","start","end","notes","status","created_at","updated_at","created_by"]},"description":"Array of appointments matching the filter criteria"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["appointments"],"summary":"Create a new appointment","description":"Creates an appointment on a case, or updates the one you already sent.\n\n**Send `external_id`.** It is your own id for the appointment, and it is the match key: a repeat call with the same `external_id` on the same case updates that appointment rather than creating a second copy, and the response echoes it back so you can map our id to yours. Without it every call inserts, which is how 189 duplicate appointments accumulated on one firm.\n\nThe response `action` field says which happened.","requestBody":{"required":true,"description":"Appointment creation data including scheduling and association details","content":{"application/json":{"schema":{"type":"object","properties":{"caseId":{"type":"string","format":"uuid","description":"The case ID to associate with the appointment. Links the appointment to a specific legal case or matter."},"external_id":{"type":"string","minLength":1,"description":"Your own id for this appointment. The match key: send it and a repeat call updates the appointment instead of creating a second one. Unique per case. Omit it and every call creates a new appointment."},"contactId":{"type":"string","format":"uuid","description":"The contact/people ID associated with the appointment. Identifies the person involved in the appointment. Optional for legal appointments."},"start":{"type":"string","description":"ISO 8601 timestamp for when the appointment starts. A date-only value (`YYYY-MM-DD`) is accepted and is the correct form for a medical visit where the source records only the day: the date is preserved and no time is shown to the client or used to schedule reminders. Send the date-only form rather than padding it to midnight — do not omit the field or skip the record."},"userId":{"type":"string","format":"uuid","description":"The user ID to assign the appointment to. If provided, this user will be responsible for the appointment."},"end":{"type":"string","description":"ISO 8601 timestamp for when the appointment ends. Required for legal appointments. Accepts the same date-only form as `start`; omit it entirely for a medical visit with no recorded time."},"notes":{"type":"string","description":"Additional notes or details about the appointment. Can include agenda items, special instructions, or other relevant information."},"type":{"type":"string","enum":["medical","legal"],"description":"Type of appointment: 'medical' for medical appointments, 'legal' for legal calendar events."},"title":{"type":"string","description":"Title/name of the appointment. Recommended for legal appointments."}},"required":["caseId","start"]},"examples":{"medical":{"summary":"Medical appointment with a contact","value":{"caseId":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","contactId":"c7e3f0a4-2b6e-4d3a-9f1b-fedcba987654","external_id":"CMS-APPT-4471","start":"2026-06-10T15:00:00.000Z","notes":"Follow-up with Dr. Patel — bring imaging from 2026-05-12 visit.","type":"medical"}},"legal":{"summary":"Legal calendar event with assigned attorney","value":{"caseId":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","userId":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","start":"2026-06-12T17:00:00.000Z","end":"2026-06-12T18:00:00.000Z","title":"Deposition prep","notes":"Review timeline, prep client for opposing counsel questions.","type":"legal"}}}}}},"responses":{"200":{"description":"Appointment created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the appointment"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this appointment, echoed back so you can map our id to yours."},"start":{"type":"string","description":"ISO timestamp for the appointment start time"},"action":{"type":"string","enum":["created","updated"],"description":"Whether a new appointment was written or the one matching your `external_id` was updated."}},"required":["id","start"]},"message":{"type":"string","description":"Success message"}},"required":["data","message"]}}}}}}},"/appointments/{id}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["appointments"],"summary":"Retrieve an appointment","description":"Retrieves detailed information about a specific appointment by its ID. Returns comprehensive appointment details including case, contact, timing, notes, and status. Only appointments belonging to the authenticated organization can be retrieved.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the appointment to retrieve"},"required":true,"description":"The unique identifier of the appointment to retrieve","name":"id","in":"path"}],"responses":{"200":{"description":"Appointment retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the appointment"},"caseId":{"type":"string","nullable":true,"description":"The case ID associated with the appointment"},"contactId":{"type":"string","nullable":true,"description":"The contact/people ID associated with the appointment"},"userId":{"type":"string","nullable":true,"description":"The user ID associated with the appointment"},"start":{"type":"string","description":"ISO timestamp for the appointment start time"},"end":{"type":"string","nullable":true,"description":"ISO timestamp for the appointment end time"},"notes":{"type":"string","nullable":true,"description":"Additional notes or details about the appointment"},"status":{"type":"string","enum":["scheduled","confirmed","rescheduled","cancelled","canceled","released"],"description":"The current status of the appointment"},"created_at":{"type":"string","nullable":true,"description":"ISO timestamp when the appointment was created"},"updated_at":{"type":"string","nullable":true,"description":"ISO timestamp when the appointment was last updated"},"created_by":{"type":"string","nullable":true,"description":"The user ID of who created the appointment"}},"required":["id","caseId","contactId","userId","start","end","notes","status","created_at","updated_at","created_by"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["appointments"],"summary":"Update appointment information","description":"Updates specific fields of an existing appointment. Allows modification of scheduling details, associated case, contact, notes, and status while maintaining data integrity. Only appointments belonging to the authenticated organization can be updated.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the appointment to update"},"required":true,"description":"The unique identifier of the appointment to update","name":"id","in":"path"}],"requestBody":{"required":true,"description":"Appointment update data","content":{"application/json":{"schema":{"type":"object","properties":{"caseId":{"type":"string","format":"uuid","description":"The case ID to associate with the appointment"},"contactId":{"type":"string","format":"uuid","description":"The contact/people ID to associate with the appointment"},"userId":{"type":"string","format":"uuid","description":"The user ID to assign the appointment to"},"start":{"type":"string","description":"ISO timestamp for the appointment start time. A date-only value (`YYYY-MM-DD`) is accepted, same as on create, for a medical visit where the source records only the day."},"end":{"type":"string","description":"ISO timestamp for the appointment end time. Accepts the same date-only form as `start`."},"notes":{"type":"string","description":"Additional notes or details about the appointment"},"status":{"type":"string","enum":["scheduled","confirmed","rescheduled","cancelled","canceled","released"],"description":"The status of the appointment"}}},"examples":{"reschedule":{"summary":"Reschedule an appointment","value":{"start":"2026-06-15T16:00:00.000Z","end":"2026-06-15T17:00:00.000Z","notes":"Rescheduled at client request."}},"cancel":{"summary":"Mark an appointment as canceled","value":{"status":"canceled"}}}}}},"responses":{"200":{"description":"Appointment updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the updated appointment"},"start":{"type":"string","description":"The new start date of the updated appointment"}},"required":["id","start"]}},"required":["message","data"]}}}}}},"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["appointments"],"summary":"Delete an appointment","description":"Permanently deletes an appointment from the organization's records. This action is irreversible and will remove all appointment data including scheduling details, notes, and associations. Only appointments belonging to the authenticated organization can be deleted.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the appointment to delete"},"required":true,"description":"The unique identifier of the appointment to delete","name":"id","in":"path"}],"responses":{"200":{"description":"Appointment successfully deleted from the organization's records","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the deletion"}},"required":["message"]}}}}}}},"/audiences":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["audiences"],"summary":"List the firm's audiences","description":"Returns every audience the firm has, with the conditions that define it. An audience is a named, reusable definition of who a message goes to — membership resolves live from the conditions rather than being a stored list, so an audience picks up clients who qualify later. Use this to reuse an existing audience on an automation instead of creating a near-duplicate.","responses":{"200":{"description":"Audiences retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"is_system":{"type":"boolean","description":"Seeded by Quilia (e.g. Active Cases) and not deletable"},"created_at":{"type":"string"},"groups":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}},"required":["field","operator","values"]}}},"required":["conditions"]}}},"required":["id","name","description","is_system","created_at","groups"]}}},"required":["message","data"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["audiences"],"summary":"Create an audience","description":"Creates a reusable audience: a named definition of who a message goes to, resolved live at send time rather than stored as a fixed list of people.\n\nThe shape is one level deep. A person matches the audience if they match ANY group; within a group, ALL conditions must match; multiple values inside one condition are OR. Groups never nest — that is where this stops being a filter and becomes a query language.\n\nRead GET /v2/audiences/options first. Case phases and case types are per-firm strings, and a value the firm has no data for is not an error — the audience just matches nobody.\n\nImportant: when building an audience that filters by `case_phase`, you should almost always include a condition for `case_status is open, invited` in the same group. Without this, the audience will match closed clients who happen to still carry that phase on their closed case. The only exception is if the phase is explicitly a closing phase (e.g. \"Closed\" or \"Archived\").","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"What the firm calls this audience"},"description":{"type":"string","nullable":true,"description":"Optional note about who this is for"},"groups":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","enum":["everyone","case_status","case_phase","case_type"],"description":"What to match on. \"everyone\" is the always-true condition — use it to say \"every client, case or not\" explicitly rather than by leaving the audience empty."},"operator":{"type":"string","enum":["is","is_not"],"default":"is","description":"\"is\" matches the values, \"is_not\" excludes them."},"values":{"type":"array","items":{"type":"string"},"default":[],"description":"The values to match. Multiple values are OR — \"case_status is open, closed\" matches either. Must be empty for \"everyone\", and non-empty for every other field. Pull valid case_phase / case_type values from GET /v2/audiences/options; a value the firm has no data for matches nobody and reports no error."}},"required":["field"]},"minItems":1,"description":"Conditions within one group are ANDed together."}},"required":["conditions"]},"minItems":1,"description":"A person matches the audience if they match ANY group; within a group, ALL conditions must match. One level only — groups never nest."}},"required":["name","groups"]}}}},"responses":{"200":{"description":"Audience created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"is_system":{"type":"boolean","description":"Seeded by Quilia (e.g. Active Cases) and not deletable"},"created_at":{"type":"string"},"groups":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}},"required":["field","operator","values"]}}},"required":["conditions"]}}},"required":["id","name","description","is_system","created_at","groups"]}},"required":["message","data"]}}}}}}},"/audiences/options":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["audiences"],"summary":"Values an audience condition can use","description":"The values this firm can build audience conditions on. Read this BEFORE creating an audience: case phases are per-firm strings — the firm's configured phase catalog plus any phase its cases still carry, so a phase with no cases in it today is still offered because an audience resolves when it is sent rather than when it is built. A guessed value is not rejected — it simply matches nobody, and the audience quietly resolves to zero people. Case types are the ones the firm has switched on in Settings → Case Types, which is not the same as the ones it currently has cases in; a type it has deactivated is not offered here even if old cases carry it. Case statuses are the full set rather than the ones in use, because a firm with no archived cases can still build an audience on \"archived\".","responses":{"200":{"description":"Options retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_status":{"type":"array","items":{"type":"string"},"description":"Every valid case status — not only the ones in use"},"case_phase":{"type":"array","items":{"type":"string"},"description":"Phases present in this firm's own cases"},"case_type":{"type":"array","items":{"type":"string"},"description":"Case types this firm has switched on in Settings → Case Types — not the ones it happens to have cases in"}},"required":["case_status","case_phase","case_type"]}},"required":["message","data"]}}}}}}},"/audiences/picked-lists":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["audiences"],"summary":"Create a picked list","description":"Creates a fixed list of clients. Unlike an audience, membership does not change unless the list is edited. Use this for a one-person automation or a small hand-maintained recipient list.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"What the firm calls this picked list"},"user_ids":{"type":"array","items":{"type":"string","format":"uuid"},"minItems":1,"maxItems":500,"description":"Client user ids to place on the fixed list. Use GET /v2/clients to find them."}},"required":["name","user_ids"]}}}},"responses":{"200":{"description":"Picked list created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"user_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"members":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid"},"name":{"type":"string","nullable":true}},"required":["user_id","name"]}},"created_at":{"type":"string"}},"required":["id","name","user_ids","members","created_at"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["audiences"],"summary":"List picked lists","description":"Returns the firm's fixed recipient lists. Use an id as group_id when creating or updating an automation.","responses":{"200":{"description":"Picked lists retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"user_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"members":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid"},"name":{"type":"string","nullable":true}},"required":["user_id","name"]}},"created_at":{"type":"string"}},"required":["id","name","user_ids","members","created_at"]}}},"required":["message","data"]}}}}}}},"/audiences/{id}":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["audiences"],"summary":"Edit an audience's name, description or conditions","description":"Changes what an audience is called or who it matches. Anything you leave out is left as it is.\n\n**Conditions are replaced, not merged.** Send `groups` and it becomes the whole definition — there is no way to add one condition to an existing group, because conditions have no stable id to address. Read the audience first (GET /v2/audiences), change what you need in the shape it gives you, and send the result back.\n\n**This changes who future sends reach, including for automations already running.** Membership is resolved at send time, not stored, so every automation pointing at this audience starts using the new definition on its next run. Messages already queued keep the recipients they were queued with — those were resolved when they were scheduled.\n\nRead GET /v2/audiences/options before changing conditions. Case phases are per-firm strings, and case types are the ones the firm has switched on in Settings → Case Types; a value outside those lists is not an error, the audience just stops matching anybody.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The audience id"},"required":true,"description":"The audience id","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"What the firm calls this audience"},"description":{"type":"string","nullable":true,"description":"Optional note about who this is for; null clears it"},"groups":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","enum":["everyone","case_status","case_phase","case_type"],"description":"What to match on. \"everyone\" is the always-true condition — use it to say \"every client, case or not\" explicitly rather than by leaving the audience empty."},"operator":{"type":"string","enum":["is","is_not"],"default":"is","description":"\"is\" matches the values, \"is_not\" excludes them."},"values":{"type":"array","items":{"type":"string"},"default":[],"description":"The values to match. Multiple values are OR — \"case_status is open, closed\" matches either. Must be empty for \"everyone\", and non-empty for every other field. Pull valid case_phase / case_type values from GET /v2/audiences/options; a value the firm has no data for matches nobody and reports no error."}},"required":["field"]},"minItems":1,"description":"Conditions within one group are ANDed together."}},"required":["conditions"]},"minItems":1,"description":"Replaces the audience definition wholesale. A person matches if they match ANY group; within a group, ALL conditions must match."}}}}}},"responses":{"200":{"description":"Audience updated","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"is_system":{"type":"boolean","description":"Seeded by Quilia (e.g. Active Cases) and not deletable"},"created_at":{"type":"string"},"groups":{"type":"array","items":{"type":"object","properties":{"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string"},"operator":{"type":"string"},"values":{"type":"array","items":{"type":"string"}}},"required":["field","operator","values"]}}},"required":["conditions"]}}},"required":["id","name","description","is_system","created_at","groups"]}},"required":["message","data"]}}}}}}},"/auth/whoami":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["auth"],"summary":"Get current API key information","description":"Returns information about the currently authenticated API key.","responses":{"200":{"description":"API key information retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the authentication status"},"data":{"type":"object","properties":{"user_id":{"type":"string","nullable":true,"format":"uuid","description":"The UUID of the user who created this API key, or null for legacy keys"},"name":{"type":"string","description":"The name of the user who created this API key"},"email":{"type":"string","nullable":true,"description":"The email of the authenticated user. Populated for OAuth-issued JWTs; null for Unkey API keys (which do not carry email)."},"organization":{"type":"string","description":"The name of the organization associated with the API key"},"org_id":{"type":"string","format":"uuid","description":"The UUID of the organization"}},"required":["user_id","name","email","organization","org_id"]}},"required":["message","data"]}}}}}}},"/automations":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["automations"],"summary":"List the firm's automations","description":"Returns every automation the firm has, paused ones included — `active: false` is paused. Worth reading before creating one: an automation that duplicates an existing rule means clients get the same message twice.","responses":{"200":{"description":"Automations retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"audience_id":{"type":"string","nullable":true},"group_id":{"type":"string","nullable":true},"action":{"type":"string","description":"What this automation does: \"send_message\" sends the subject and body; \"ask_feedback\" asks for an NPS score and has no message copy of its own, so an empty subject and body are correct for it."},"anchor_field":{"type":"string"},"anchor_offset":{"type":"object","properties":{"value":{"type":"number","description":"Signed: negative is before the anchor"},"unit":{"type":"string"}},"required":["value","unit"]},"custom_send_time":{"type":"string","nullable":true},"recurrence":{"type":"object","nullable":true,"properties":{"frequency_type":{"type":"string","nullable":true},"frequency":{"type":"number","nullable":true}},"required":["frequency_type","frequency"]},"message_subject":{"type":"string","nullable":true},"message_body":{"type":"string","nullable":true},"message_body_markdown":{"type":"string","description":"The base copy as markdown, ready to send straight back to PATCH. Empty for an automation stored with no blocks."},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string"},"message_subject":{"type":"string","nullable":true},"message_body":{"type":"string","description":"Markdown, ready to send straight back to PATCH"},"stale":{"type":"boolean","nullable":true,"description":"True once the English has been edited since this was written, so it now says something different. Null for translations written before the fingerprint existed — unknown, rather than a guess in either direction."}},"required":["language","message_subject","message_body","stale"]},"description":"Every language this automation has copy for. Sending `translations` on an update REPLACES this whole set, so read it first and send it back complete — omitting a language deletes it."},"channels":{"type":"object","properties":{"sms":{"type":"string","enum":["always","fallback","never"]},"email":{"type":"boolean"}},"required":["sms","email"],"description":"What this automation actually sends on. Push is always on and is not listed. A firm that never chose gets the default, so this is never empty."},"active":{"type":"boolean","description":"False means paused: it exists, and it sends nothing"},"created_at":{"type":"string"}},"required":["id","name","audience_id","group_id","action","anchor_field","anchor_offset","custom_send_time","recurrence","message_subject","message_body","message_body_markdown","translations","channels","active","created_at"]}}},"required":["message","data"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["automations"],"summary":"Create an automation (paused)","description":"Creates an automation: a standing rule that turns a date into a message. Who (an audience), when (an anchor date plus an offset), how often, what to say, and how it reaches them (`channels`).\n\n**By default it sends on all three channels** — push, SMS and email. Push is always on and cannot be turned off; `channels` is how you narrow the other two.\n\n**By default it sends as the firm.** `send_as` sets whose name the client sees; pass a staff id to sign it as a person. This endpoint used to stamp the calling user as the sender with no way to say otherwise, so automations created over the API went out signed by whoever built them.\n\n**It is created paused.** An automation built over the API sends nothing until a human turns it on in the portal — the Automations list has the control. A wrong audience or a wrong offset is not a typo here, it is a message to every client who matches, so the last step stays with a person.\n\nOnce it is switched on, the daily sweep picks it up and queues sends for everyone whose anchor date is still ahead of them. It never reaches backwards: a client whose anchor already passed is skipped, which is what stops switching on a \"when the case closes\" automation from messaging a firm's entire history.\n\n**Requires an organization admin.** An automation is a standing rule that messages the firm's clients, so it is gated like org settings and team management.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"What the firm calls this automation in the Automations list"},"audience_id":{"type":"string","format":"uuid","description":"The audience to send to. Create one with POST /v2/audiences or reuse one from GET /v2/audiences. Exactly one of audience_id or group_id is required."},"group_id":{"type":"string","format":"uuid","description":"A picked list of people (the older model) instead of an audience. Prefer audience_id — a list is a fixed set of people and never picks up clients who qualify later."},"anchor":{"type":"string","enum":["case_opened","case_closed","case_invited","case_phase_changed","client_birthday"],"description":"The date to count from. case_phase_changed is per person per case, so co-clients on one case can trigger at different times. client_birthday recurs every year; the others happen once."},"direction":{"type":"string","enum":["before","on","after"],"default":"on","description":"\"on\" sends at the anchor itself and ignores the offset; \"before\" and \"after\" apply it."},"offset_value":{"type":"integer","minimum":0,"default":0,"description":"How far from the anchor, as a positive number"},"offset_unit":{"type":"string","enum":["days","weeks","months","years"],"default":"days","description":"Offset unit"},"send_time":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","default":"09:00","description":"Time of day to send, 24-hour, in the recipient's own time zone. Sends are still held to the firm's allowed send window."},"repeat":{"type":"string","enum":["once","interval","yearly"],"default":"once","description":"\"once\" sends a single message per person; \"interval\" repeats every offset (e.g. every 30 days); \"yearly\" repeats annually."},"message_subject":{"type":"string","minLength":1,"description":"The subject line clients see. Merge variables: {{client_first_name}}, {{client_last_name}}, {{client_full_name}}, {{sender_first_name}}, {{sender_last_name}}, {{sender_full_name}}, {{firm_name}}. They are filled per recipient at send time. Anything else in double braces is left as literal text in front of the client."},"message_body":{"type":"string","minLength":1,"description":"The message, as MARKDOWN. Supported: paragraphs, **bold**, *italic*, [links](https://…) and bullet or numbered lists, which may be nested by indenting two spaces. Headings, images, tables, block quotes and raw HTML are rejected rather than passed through as literal characters. Merge variables: {{client_first_name}}, {{client_last_name}}, {{client_full_name}}, {{sender_first_name}}, {{sender_last_name}}, {{sender_full_name}}, {{firm_name}}. They are filled per recipient at send time. Anything else in double braces is left as literal text in front of the client. To link into the Quilia app use https://quilia.com/app/home, /app/inbox, /app/suggestions, /app/appointments (their treatment review), /app/case/check-in, /app/case/case-note, /app/case/wage-loss, /app/providers, /app/documents or /app/chat. These open the app for clients who have it and the web for everyone else. Three of them are conditional, and none of them tells you when it misses: two open the app on Home, exactly like an unrecognised path, and the third opens a screen the client has no other way to reach. /app/chat is CaseChat, the two-way conversation, and only works if the firm has case_chat_enabled on. Ask a Question is a DIFFERENT feature on its own toggle, ask_question_enabled — it sits on the firm's Organization screen and has no deep link, so name it rather than linking it. Both flags come back in client_features from get_firm_settings, and a firm may have either, both or neither, so read them rather than guessing. /app/providers is the Doctor List, and works only on case types with a providers screen; case types such as family law, criminal defense and landlord tenant do not have one. /app/case/wage-loss is where a client records time off work, and it holds the employer and doctor verification forms almost nobody finds unless you send them there. It is available only on case types configured with the wage-loss feature, and it fails the OTHER way: on unsupported case types the link opens the screen anyway, empty and reachable by no other route, so check the audience case types for that feature rather than leaving it to the link. Its NAME also moves with the case type — Lost Income on most, Wages on workers compensation, Employment on social security disability, product liability and wc third party — so name the screen only when the audience is one case type, and otherwise write what it is for. /app/case/case-note is Notes, the client's own running journal of their case, and it is the one destination on every single case type, so it is always safe to link. /app/documents is Files, which holds only what the client uploaded, so link it to ask for something and never to offer a look at what the firm has. No other path works — an unrecognised one opens the app on Home with no error, so do not invent one."},"channels":{"type":"object","properties":{"sms":{"type":"string","enum":["always","fallback","never"],"description":"\"always\" texts every client with a phone number; \"fallback\" texts only the ones the app cannot reach; \"never\" texts nobody. Defaults to \"always\"."},"email":{"type":"boolean","description":"Whether to email as well. Defaults to true."}},"description":"Which channels this automation sends on. Push is always on and is not configurable — the app is the only client surface, so every automation pushes. Omit this object entirely to send on all three, which is the standing default."},"send_as":{"type":"string","minLength":1,"description":"Who the message comes from, as the client sees it. \"firm\" (the default) sends as the firm itself. Otherwise the id of a member of staff at this firm — clients then see the message from that person by name. Client ids, staff at other firms, and Quilia support (wizard) accounts are rejected: a name on a client's message has to be someone who actually works at the firm."},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"Language code this copy is for, e.g. \"es\". The full set is every language Quilia speaks; \"en\" is not one of them, because the base body is the English."},"message_subject":{"type":"string","minLength":1,"description":"Subject in this language. Falls back to the base subject."},"message_body":{"type":"string","minLength":1,"description":"Body in this language, in the same markdown subset as the base"}},"required":["language","message_body"]},"description":"Per-language copy, written by the caller. Clients reading a language listed here receive that copy; everyone else receives the base body, so a language you leave out costs nobody their message. Do not include \"en\" — the base body is the English."}},"required":["name","anchor","message_subject","message_body"]}}}},"responses":{"200":{"description":"Automation created successfully, paused","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"audience_id":{"type":"string","nullable":true},"group_id":{"type":"string","nullable":true},"action":{"type":"string","description":"What this automation does: \"send_message\" sends the subject and body; \"ask_feedback\" asks for an NPS score and has no message copy of its own, so an empty subject and body are correct for it."},"anchor_field":{"type":"string"},"anchor_offset":{"type":"object","properties":{"value":{"type":"number","description":"Signed: negative is before the anchor"},"unit":{"type":"string"}},"required":["value","unit"]},"custom_send_time":{"type":"string","nullable":true},"recurrence":{"type":"object","nullable":true,"properties":{"frequency_type":{"type":"string","nullable":true},"frequency":{"type":"number","nullable":true}},"required":["frequency_type","frequency"]},"message_subject":{"type":"string","nullable":true},"message_body":{"type":"string","nullable":true},"message_body_markdown":{"type":"string","description":"The base copy as markdown, ready to send straight back to PATCH. Empty for an automation stored with no blocks."},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string"},"message_subject":{"type":"string","nullable":true},"message_body":{"type":"string","description":"Markdown, ready to send straight back to PATCH"},"stale":{"type":"boolean","nullable":true,"description":"True once the English has been edited since this was written, so it now says something different. Null for translations written before the fingerprint existed — unknown, rather than a guess in either direction."}},"required":["language","message_subject","message_body","stale"]},"description":"Every language this automation has copy for. Sending `translations` on an update REPLACES this whole set, so read it first and send it back complete — omitting a language deletes it."},"channels":{"type":"object","properties":{"sms":{"type":"string","enum":["always","fallback","never"]},"email":{"type":"boolean"}},"required":["sms","email"],"description":"What this automation actually sends on. Push is always on and is not listed. A firm that never chose gets the default, so this is never empty."},"active":{"type":"boolean","description":"False means paused: it exists, and it sends nothing"},"created_at":{"type":"string"}},"required":["id","name","audience_id","group_id","action","anchor_field","anchor_offset","custom_send_time","recurrence","message_subject","message_body","message_body_markdown","translations","channels","active","created_at"]}},"required":["message","data"]}}}}}}},"/automations/{id}":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["automations"],"summary":"Edit an automation's copy or channels, or pause it","description":"Changes what an automation says, which channels it sends on, or pauses it. Anything you leave out is left as it is.\n\n**A running automation's pending sends are rewritten too.** Both the copy and the channels are stamped onto each message when it is queued, so an edit that only touched the automation would leave everyone already in the queue receiving the old wording on the old channels. This updates both.\n\n**The schedule and audience can be changed, but only before anything has been queued.** `anchor`, `direction`, `offset_value`, `offset_unit`, `repeat`, `send_time`, `audience_id` and `group_id` are accepted while the automation is paused and has no scheduled sends — which is every automation this API creates, right up until a human switches it on. There is no queue yet, so there is nothing to rebuild. Once it has queued anything, schedule changes and audience swaps require rebuilding the queue, which stays in the portal.\n\n**It cannot turn an automation on.** `active` accepts only `false`. Activation queues sends to every matching client, which is the one step `POST /v2/automations` deliberately leaves to a person — this endpoint keeps it that way.\n\nEditing the base body does **not** re-translate. Existing translations are kept and become stale against the new English, which the portal flags so a human can rewrite them. Send `translations` yourself to replace them.\n\n**Requires an organization admin.** An automation is a standing rule that messages the firm's clients, so it is gated like org settings and team management.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The automation id"},"required":true,"description":"The automation id","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"What the firm calls this automation in the Automations list"},"message_subject":{"type":"string","minLength":1,"description":"The subject line clients see. Merge variables: {{client_first_name}}, {{client_last_name}}, {{client_full_name}}, {{sender_first_name}}, {{sender_last_name}}, {{sender_full_name}}, {{firm_name}}. They are filled per recipient at send time. Anything else in double braces is left as literal text in front of the client."},"message_body":{"type":"string","minLength":1,"description":"The message, as MARKDOWN, in the same subset the create endpoint accepts. Editing this does NOT re-translate: existing translations are kept and go stale, which the portal shows so a human can rewrite them. Merge variables: {{client_first_name}}, {{client_last_name}}, {{client_full_name}}, {{sender_first_name}}, {{sender_last_name}}, {{sender_full_name}}, {{firm_name}}. They are filled per recipient at send time. Anything else in double braces is left as literal text in front of the client. To link into the Quilia app use https://quilia.com/app/home, /app/inbox, /app/suggestions, /app/appointments (their treatment review), /app/case/check-in, /app/case/case-note, /app/case/wage-loss, /app/providers, /app/documents or /app/chat. These open the app for clients who have it and the web for everyone else. Three of them are conditional, and none of them tells you when it misses: two open the app on Home, exactly like an unrecognised path, and the third opens a screen the client has no other way to reach. /app/chat is CaseChat, the two-way conversation, and only works if the firm has case_chat_enabled on. Ask a Question is a DIFFERENT feature on its own toggle, ask_question_enabled — it sits on the firm's Organization screen and has no deep link, so name it rather than linking it. Both flags come back in client_features from get_firm_settings, and a firm may have either, both or neither, so read them rather than guessing. /app/providers is the Doctor List, and works only on case types with a providers screen; case types such as family law, criminal defense and landlord tenant do not have one. /app/case/wage-loss is where a client records time off work, and it holds the employer and doctor verification forms almost nobody finds unless you send them there. It is available only on case types configured with the wage-loss feature, and it fails the OTHER way: on unsupported case types the link opens the screen anyway, empty and reachable by no other route, so check the audience case types for that feature rather than leaving it to the link. Its NAME also moves with the case type — Lost Income on most, Wages on workers compensation, Employment on social security disability, product liability and wc third party — so name the screen only when the audience is one case type, and otherwise write what it is for. /app/case/case-note is Notes, the client's own running journal of their case, and it is the one destination on every single case type, so it is always safe to link. /app/documents is Files, which holds only what the client uploaded, so link it to ask for something and never to offer a look at what the firm has. No other path works — an unrecognised one opens the app on Home with no error, so do not invent one."},"send_as":{"type":"string","minLength":1,"description":"Change who the message comes from: \"firm\", or the id of a member of staff at this firm — not a client, and not a Quilia support (wizard) account. Applied to the sends already queued as well, so correcting a wrongly-signed automation also fixes the messages about to go out."},"channels":{"type":"object","properties":{"sms":{"type":"string","enum":["always","fallback","never"],"description":"\"always\" texts every client with a phone number; \"fallback\" texts only the ones the app cannot reach; \"never\" texts nobody. Defaults to \"always\"."},"email":{"type":"boolean","description":"Whether to email as well. Defaults to true."}},"description":"Which channels this automation sends on. Only the fields you send are changed — passing just `{\"sms\": \"never\"}` leaves email as it was. Like the copy, this is also applied to the sends already queued, so turning SMS off stops the texts that were about to go out rather than only the ones queued from now on."},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"Language code this copy is for, e.g. \"es\". The full set is every language Quilia speaks; \"en\" is not one of them, because the base body is the English."},"message_subject":{"type":"string","minLength":1,"description":"Subject in this language. Falls back to the base subject."},"message_body":{"type":"string","minLength":1,"description":"Body in this language, in the same markdown subset as the base"}},"required":["language","message_body"]},"description":"Per-language copy. Sending this REPLACES every translation the automation has — send the full set, not a delta. Omit it to leave existing translations untouched."},"audience_id":{"type":"string","format":"uuid","description":"Point the automation at a different audience. Only allowed while it is paused and has queued nothing — see the endpoint description. Setting this clears group_id."},"group_id":{"type":"string","format":"uuid","description":"Point the automation at a picked list instead. Same restriction as audience_id, and setting this clears audience_id."},"active":{"type":"boolean","enum":[false],"description":"Pass false to pause the automation. Turning one back ON is done in the portal: activation queues sends to every matching client, so it stays a human decision."},"anchor":{"type":"string","enum":["case_opened","case_closed","case_invited","case_phase_changed","client_birthday"],"description":"The date to count from. Only allowed while paused and unqueued."},"direction":{"type":"string","enum":["before","on","after"],"description":"\"on\" sends at the anchor itself and ignores the offset; \"before\" and \"after\" apply it. Only allowed while paused and unqueued."},"offset_value":{"type":"integer","minimum":0,"description":"How far from the anchor, as a positive number. Only allowed while paused and unqueued."},"offset_unit":{"type":"string","enum":["days","weeks","months","years"],"description":"Offset unit. Only allowed while paused and unqueued."},"send_time":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$","description":"Time of day to send, 24-hour. Only allowed while paused and unqueued."},"repeat":{"type":"string","enum":["once","interval","yearly"],"description":"\"once\" sends a single message per person; \"interval\" repeats every offset; \"yearly\" repeats annually. Only allowed while paused and unqueued."}},"description":"Fields to change. Anything omitted is left as it is."}}}},"responses":{"200":{"description":"Automation updated","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"audience_id":{"type":"string","nullable":true},"group_id":{"type":"string","nullable":true},"action":{"type":"string","description":"What this automation does: \"send_message\" sends the subject and body; \"ask_feedback\" asks for an NPS score and has no message copy of its own, so an empty subject and body are correct for it."},"anchor_field":{"type":"string"},"anchor_offset":{"type":"object","properties":{"value":{"type":"number","description":"Signed: negative is before the anchor"},"unit":{"type":"string"}},"required":["value","unit"]},"custom_send_time":{"type":"string","nullable":true},"recurrence":{"type":"object","nullable":true,"properties":{"frequency_type":{"type":"string","nullable":true},"frequency":{"type":"number","nullable":true}},"required":["frequency_type","frequency"]},"message_subject":{"type":"string","nullable":true},"message_body":{"type":"string","nullable":true},"message_body_markdown":{"type":"string","description":"The base copy as markdown, ready to send straight back to PATCH. Empty for an automation stored with no blocks."},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string"},"message_subject":{"type":"string","nullable":true},"message_body":{"type":"string","description":"Markdown, ready to send straight back to PATCH"},"stale":{"type":"boolean","nullable":true,"description":"True once the English has been edited since this was written, so it now says something different. Null for translations written before the fingerprint existed — unknown, rather than a guess in either direction."}},"required":["language","message_subject","message_body","stale"]},"description":"Every language this automation has copy for. Sending `translations` on an update REPLACES this whole set, so read it first and send it back complete — omitting a language deletes it."},"channels":{"type":"object","properties":{"sms":{"type":"string","enum":["always","fallback","never"]},"email":{"type":"boolean"}},"required":["sms","email"],"description":"What this automation actually sends on. Push is always on and is not listed. A firm that never chose gets the default, so this is never empty."},"active":{"type":"boolean","description":"False means paused: it exists, and it sends nothing"},"created_at":{"type":"string"}},"required":["id","name","audience_id","group_id","action","anchor_field","anchor_offset","custom_send_time","recurrence","message_subject","message_body","message_body_markdown","translations","channels","active","created_at"]},"queued_rewritten":{"type":"integer","nullable":true,"description":"Number of already-queued sends rewritten by this edit. null when the edit could not reach the queue (rename, pause); 0 when nothing was queued."}},"required":["message","data","queued_rewritten"]}}}}}},"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["automations"],"summary":"Delete an automation and cancel what it has queued","description":"Deletes the automation and removes every send it still had waiting.\n\nThe order matters and is not an implementation detail: a queued message carries its own copy and its own send date, so deleting the rule without clearing the queue leaves messages that still go out with nothing left to explain them. The queue is cleared first, and if that fails the automation is left in place rather than half-removed.\n\nOnly messages still waiting are touched. Anything already sent stays exactly where it is — it is a record of something a client received, and deleting the rule that produced it does not unsend it.\n\n**Requires an organization admin.** An automation is a standing rule that messages the firm's clients, so it is gated like org settings and team management.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The automation id"},"required":true,"description":"The automation id","name":"id","in":"path"}],"responses":{"200":{"description":"Automation deleted","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"boolean","enum":[true]},"cancelled_messages":{"type":"number","description":"Queued sends removed along with it"}},"required":["id","deleted","cancelled_messages"]}},"required":["message","data"]}}}}}}},"/cases":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Create a new case","description":"Creates a case, optionally with its client and everything else you hold on it.\n\n**Send the whole case in one call.** `providers`, `insurance`, `employments`, `incident`, `damage` and `staff` are all optional and all accept the same body as their standalone endpoints. Pushing one case used to take eight requests.\n\n**One bad child never costs you the case.** Every child is validated and written on its own. The case and the good children land, and the response carries a `results` array with one entry per object you sent — `ok`, our `id`, whether it was `created` or `updated`, and on failure the reason. Match entries back by the `external_id` you sent, or by `index` for objects you sent without one.\n\n**Re-pushing is safe.** Send `external_id` on the case and on each child and a repeat call updates rather than duplicates, on this endpoint and on the standalone ones alike. Children are written on a re-push too, so a caller never has to know whether we already held the case.\n\nStaff are created if their email is new to the organization and then attached, which is the two calls `POST /v2/staff` and `POST /v2/cases/{id}/members` used to take. No invitation email is sent unless you ask for one.\n\nInjuries have no write endpoint yet and so cannot be sent here.","requestBody":{"required":true,"description":"Case creation data","content":{"application/json":{"schema":{"type":"object","properties":{"new_client":{"type":"object","properties":{"external_id":{"type":"string","description":"Your own id for this person. Used to match them on a re-push, in preference to their phone number, and echoed back on every response so you can correlate. Send it and a mistyped phone can no longer read as a second claimant."},"name":{"type":"string","description":"The name of the client"},"name_first":{"type":"string","description":"The first name of the client"},"name_last":{"type":"string","description":"The last name of the client"},"phone":{"type":"string","description":"The phone number of the client. Normalized to E.164, so a 10-digit US number or one carrying spaces, dashes or parentheses is fine."},"language_code":{"type":"string","description":"The language code of the client"},"email":{"type":"string","description":"The email of the client. An address that does not parse is dropped and the case is still created, so a placeholder your staff typed to satisfy a required field will never cost you the record."},"address_1":{"type":"string","description":"The first line of the address"},"address_2":{"type":"string","description":"The second line of the address"},"city":{"type":"string","description":"The city"},"state":{"type":"string","description":"The state or province"},"postal_code":{"type":"string","description":"The postal code"},"country":{"type":"string","description":"The country"},"date_of_birth":{"type":"string","description":"The date of birth. YYYY-MM-DD, or an ISO timestamp, which is truncated to its date."}},"required":["name","phone"],"description":"The client to associate with the case. Accepts the same fields as POST /v2/clients — send everything you have on the first call rather than following up with PATCH /v2/clients/{id}."},"invite":{"type":"boolean","description":"Whether to text the client their invite. Defaults to the firm's auto-invite setting on this integration, so omit it to keep that behaviour and send it to override the default either way. A client who has already activated is never texted again regardless."},"client_id":{"type":"string","description":"The ID of an existing client"},"organization_integration_id":{"type":"string","description":"The ID of the organization integration to use"},"cms_type":{"type":"string","description":"Look up integration by CMS type when ID is absent"},"type":{"type":"string","description":"The type of the case. Can be a Quilia case type or a custom CMS case type that will be mapped via integration settings."},"external_id":{"type":"string","description":"Your own id for this case. The match key: send it and a repeat call updates the case instead of creating a second one. Omit it and every call creates a new case."},"native_id":{"type":"string","description":"Synonym for `external_id`, kept so existing integrations keep working. Prefer `external_id` in new code; if both are sent, `external_id` wins."},"case_email":{"type":"string","format":"email","description":"The case's own inbox address in the external system, e.g. a CasePacer filing address. For a CMS with no API this is how Quilia delivers activity back into the case, so a case created without it is linked but unreachable. Must not already belong to another case."},"phase":{"type":"string","description":"The current phase of the case"},"cms_staff_names":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"maxItems":20,"description":"Staff names observed on the CMS case. The server resolves saved integration mappings and adds the matching Quilia staff, including staff configured for every case. This does not write assignments back to the CMS."},"status":{"type":"string","nullable":true,"enum":["pending","open","closed"],"description":"The status of the case"},"opened_at":{"type":"string","nullable":true,"format":"date-time","description":"The date and time when the case was opened"},"created_at":{"type":"string","format":"date-time","description":"The date and time when the case was created"},"updated_at":{"type":"string","format":"date-time","description":"The date and time when the case was last updated"},"providers":{"type":"array","items":{"nullable":true},"maxItems":200,"description":"Medical providers to record on the case. Same body as `POST /v2/cases/{id}/providers`. Send `external_id` on each to make a re-push idempotent."},"insurance":{"type":"array","items":{"nullable":true},"maxItems":200,"description":"Insurance policies. Same body as `POST /v2/cases/{id}/insurance`. Send `external_id` on each to make a re-push idempotent."},"employments":{"type":"array","items":{"nullable":true},"maxItems":200,"description":"Employment records. Same body as `POST /v2/cases/{id}/employments`. Send `external_id` on each to make a re-push idempotent."},"incident":{"nullable":true,"description":"The incident. One per case, so it is an object rather than a list and a re-push merges into the existing row. Same body as `PUT /v2/cases/{id}/incident`."},"damage":{"nullable":true,"description":"The vehicle damage. One per case, same merge behaviour as `incident`. Same body as `PUT /v2/cases/{id}/damage`."},"staff":{"type":"array","items":{"nullable":true},"maxItems":200,"description":"Firm staff to put on the case. Creates the staff member if their email is new to the organization, then attaches them — the two calls that `POST /v2/staff` plus `POST /v2/cases/{id}/members` used to take, and without the silent skip that dropped staff who were not org members yet (QUILIA-5995). No invitation email is sent unless a member sets `invite: \"send\"`."}},"required":["type"]},"examples":{"withNewClient":{"summary":"Create a case with a new client","value":{"type":"auto-accident","status":"open","opened_at":"2026-05-14T15:00:00.000Z","new_client":{"name":"Jane Doe","name_first":"Jane","name_last":"Doe","phone":"+15551234567","email":"jane.doe@example.com","language_code":"en","address_1":"123 Main St","city":"Springfield","state":"IL","postal_code":"62701","country":"US","date_of_birth":"1985-06-15"}}},"withExistingClient":{"summary":"Create a case for an existing client","value":{"type":"slip-and-fall","status":"open","client_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345"}},"wholeCase":{"summary":"The whole case in one call","value":{"type":"auto-accident","status":"open","external_id":"CMS-12345","new_client":{"external_id":"CMS-CLIENT-77","name":"Jane Doe","phone":"+15551234567"},"incident":{"date_of_injury":"2026-05-14","incident_location":"Main St & 3rd Ave, Springfield IL","what_happened_during":"Rear-ended at a stop light."},"damage":{"vehicle_year":2021,"vehicle_make":"Toyota","vehicle_model":"Camry"},"providers":[{"external_id":"CMS-PROVIDER-789","name":"Mercy General Hospital","specialty":"Emergency Medicine"}],"insurance":[{"external_id":"CMS-POLICY-1","type":"First Party Car","company":"State Farm","policy_number":"SF-4471902"},{"external_id":"CMS-POLICY-2","type":"Health","claim_number":"77-9921-C"}],"employments":[{"external_id":"CMS-JOB-3","company_name":"Acme Corporation","job_title":"Warehouse Lead"}],"staff":[{"name":"Dean Tingey","email":"dean@example.com","role":"attorney"}]}},"fromCmsIntegration":{"summary":"Create a case mapped to an external CMS record","value":{"type":"Auto Accident","phase":"Intake","status":"open","native_id":"CMS-12345","cms_type":"clio","opened_at":"2026-05-14T15:00:00.000Z","new_client":{"name":"Jane Doe","phone":"+15551234567"}}}}}}},"responses":{"200":{"description":"Case created successfully or already exists","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the creation operation"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"status":{"type":"string"},"opened_at":{"type":"string","nullable":true},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"type":{"type":"string"},"phase":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"status":{"type":"string"},"member_id":{"type":"string"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this person, if we hold one. Send it on `new_client` and it comes back here, so you can match our members against the objects you sent."}},"required":["user_id","status"]}},"staff":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"member_id":{"type":"string"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this staff member, if we hold one."},"status":{"type":"string"},"role":{"type":"string","nullable":true,"description":"`attorney`, `legal staff`, `admin`."}},"required":["user_id","status"]},"description":"The firm staff assigned to the case. Separate from `members`, which is claimants only, so iterating members to decide who to contact can never reach the firm."},"staff_skipped":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","description":"A requested user_id that was not added"},"reason":{"type":"string","enum":["already_member","not_org_member"],"description":"`already_member`: already on the case. `not_org_member`: the id is not a matching-role member of this organization — for staff, create them via POST /v2/staff first."}},"required":["user_id","reason"]},"description":"Mapped Quilia staff IDs that were not inserted, including users already on the case and IDs that are not firm staff."}},"required":["case_id","status","opened_at","created_at","updated_at","type","members"]},"results":{"type":"array","items":{"type":"object","properties":{"object":{"type":"string","enum":["provider","insurance","employment","incident","damage","staff"]},"index":{"type":"number","description":"Position in the list you sent. The only handle on an object with no id of its own."},"external_id":{"type":"string","nullable":true},"ok":{"type":"boolean"},"id":{"type":"string","description":"Our id for the row, when one was written"},"action":{"type":"string","enum":["created","updated"],"description":"Whether the row was written or matched. Only the writers that distinguish the two report it — incident, damage and employment merge without saying which, so it is absent for those."},"error":{"type":"string","description":"Why it was not written. Present only when `ok` is false."}},"required":["object","index","external_id","ok"]},"description":"One entry per child object you sent, in the order you sent it. Present only when the call carried children. A failed entry has not been written and the rest of the call still stands — the case is never lost to one bad provider."}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List cases","description":"Retrieves a paginated list of cases for the authenticated organization.\n\n## Filtering\n\nUse `filter[field]=value` query parameters:\n\n- `filter[status]` - Case status: \"pending\", \"open\", \"closed\", \"invited\", \"archived\"\n- `filter[type]` - Case type (e.g., \"motor vehicle collision\")\n- `filter[client_name]` - Client name (cases without a client are excluded when using this filter)\n- `filter[client_id]` - Client ID (filters by user_id)\n\n**Partial matching**: All filters match substrings by default.\nUse `*` for explicit wildcard placement (e.g., `motor*` for \"starts with\").\n\n**Fuzzy enum matching**: Enum fields (status, type) use fuzzy matching automatically.\n\n**Multiple values**: Comma-separated for OR matching (e.g., `filter[status]=open,closed`).\n\nNote: Combining wildcards with commas is not supported.","parameters":[{"schema":{"type":"number","nullable":true,"default":10,"description":"The maximum number of cases to return."},"required":false,"description":"The maximum number of cases to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"The number of cases to skip before starting to return results."},"required":false,"description":"The number of cases to skip before starting to return results.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter by status. See endpoint description for syntax."},"required":false,"description":"Filter by status. See endpoint description for syntax.","name":"filter[status]","in":"query"},{"schema":{"type":"string","description":"Filter by type. See endpoint description for syntax."},"required":false,"description":"Filter by type. See endpoint description for syntax.","name":"filter[type]","in":"query"},{"schema":{"type":"string","description":"Filter by client_name. See endpoint description for syntax."},"required":false,"description":"Filter by client_name. See endpoint description for syntax.","name":"filter[client_name]","in":"query"},{"schema":{"type":"string","description":"Filter by client_id. See endpoint description for syntax."},"required":false,"description":"Filter by client_id. See endpoint description for syntax.","name":"filter[client_id]","in":"query"}],"responses":{"200":{"description":"List of cases retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the case"},"status":{"type":"string","description":"The current status of the case (e.g., \"open\", \"closed\")"},"type":{"type":"string","description":"The type/category of the case (e.g., \"motor vehicle collision\")"},"case_phase":{"type":"string","nullable":true,"description":"The current phase of the case workflow"},"opened_at":{"type":"string","nullable":true,"description":"The date and time when the case was opened"},"user_id":{"type":"string","nullable":true,"description":"The ID of the primary client associated with the case"},"client_name":{"type":"string","nullable":true,"description":"The name of the primary client associated with the case"},"created_at":{"type":"string","nullable":true,"description":"The date and time when the case was created"},"updated_at":{"type":"string","nullable":true,"description":"The date and time when the case was last updated"}},"required":["id","status","type","case_phase","opened_at","user_id","client_name","created_at","updated_at"]},"description":"Array of cases"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/cases/{id}":{"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Delete a case","description":"Permanently deletes a case from the organization's records. This action is irreversible and will remove all case data, including associated members, documents, and chat history. Only cases belonging to the authenticated organization can be deleted.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case to delete"},"required":true,"description":"The unique identifier of the case to delete","name":"id","in":"path"}],"responses":{"200":{"description":"Case successfully deleted from the organization's records","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the delete operation"}},"required":["message"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve an individual case","description":"Retrieves detailed information about a specific case by its ID. Returns comprehensive case metadata including status, timestamps, type, associated client and organization information, and case members.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case to retrieve"},"required":true,"description":"The unique identifier of the case to retrieve","name":"id","in":"path"}],"responses":{"200":{"description":"Case retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the case"},"status":{"type":"string","description":"The current status of the case"},"opened_at":{"type":"string","nullable":true,"description":"The date and time when the case was opened"},"created_at":{"type":"string","nullable":true,"description":"The date and time when the case was created"},"updated_at":{"type":"string","nullable":true,"description":"The date and time when the case was last updated"},"type":{"type":"string","description":"The type/category of the case"},"user_id":{"type":"string","nullable":true,"description":"The ID of the client associated with the case"},"organization_id":{"type":"string","nullable":true,"description":"The ID of the organization that owns the case"},"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the case member"},"case_id":{"type":"string","description":"The case ID this member belongs to"},"user_id":{"type":"string","nullable":true,"description":"The user ID of the member"},"status":{"type":"string","nullable":true,"description":"The status of the member in the case"},"case_phase":{"type":"string","nullable":true,"description":"The current phase of the case for this member"},"phase_id":{"type":"string","nullable":true,"description":"The phase ID for this member"},"phase_updated_at":{"type":"string","nullable":true,"description":"When the phase was last updated for this member"},"allow_messages":{"type":"boolean","description":"Whether the member can send messages"},"contactable":{"type":"boolean","description":"Whether the member can be contacted"},"invited_at":{"type":"string","nullable":true,"description":"When the member was invited"},"created_at":{"type":"string","nullable":true,"description":"When the member was added to the case"},"updated_at":{"type":"string","nullable":true,"description":"When the member was last updated"}},"required":["id","case_id","user_id","status","case_phase","phase_id","phase_updated_at","allow_messages","contactable","invited_at","created_at","updated_at"]},"description":"List of case members"}},"required":["id","status","opened_at","created_at","updated_at","type","user_id","organization_id","members"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Update case details","description":"Updates specific fields of an existing case. Allows modification of case status, type, opening date, and custom CMS data. Only the provided fields will be updated, maintaining data integrity.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case to update"},"required":true,"description":"The unique identifier of the case to update","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["open","closed"],"description":"The status of the case"},"type":{"type":"string","description":"The type/category of the case"},"opened_at":{"type":"string","description":"The date and time when the case was opened (ISO 8601 format)"},"cms_data":{"nullable":true,"description":"Additional custom data for the case"}}},"example":{"status":"closed","opened_at":"2026-05-14T15:00:00.000Z","cms_data":{"external_ref":"CMS-12345"}}}}},"responses":{"200":{"description":"Case updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"type":{"type":"string"},"cms_data":{"type":"object","nullable":true,"properties":{}},"opened_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true}},"required":["id","status","type","cms_data","opened_at","updated_at"]}},"required":["message","data"]}}}}}}},"/cases/{id}/invite":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Invite users to a case","description":"Invites one or more users to participate in a specific case with designated roles (client or staff). Manages case access permissions and user associations for collaborative case management.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the case to invite users to"},"required":true,"description":"The unique identifier of the case to invite users to","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","items":{"type":"string","format":"uuid","description":"User ID"},"description":"An array of user IDs to invite to the case"},"role":{"type":"string","enum":["client","staff"],"description":"The role to assign to the invited users"},"contactable":{"type":"boolean","description":"Whether the invited users' contact info is visible to clients in the app"}},"required":["users","role"]},"example":{"users":["7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","8c1f6d12-3b4a-4a9d-8f0c-1234567890ab"],"role":"client","contactable":true}}}},"responses":{"200":{"description":"Users invited successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the invite operation"},"data":{"type":"object","properties":{"invited_users":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","nullable":true,"description":"The ID of the invited user"},"case_id":{"type":"string","description":"The ID of the case the user was invited to"},"status":{"type":"string","nullable":true,"description":"The status of the invitation"},"role":{"type":"string","enum":["client","staff"],"description":"The role assigned to the user"}},"required":["user_id","case_id","status","role"]},"description":"List of users successfully invited to the case"},"skipped":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","description":"A requested user_id that was not added"},"reason":{"type":"string","enum":["already_member","not_org_member"],"description":"`already_member`: already on the case. `not_org_member`: the id is not a matching-role member of this organization — for staff, create them via POST /v2/staff first."}},"required":["user_id","reason"]},"description":"Requested users that were already members and not re-invited"}},"required":["invited_users","skipped"]}},"required":["message","data"]}}}}}}},"/cases/casetypes":{"get":{"tags":["cases"],"summary":"List available case types","description":"Retrieves a list of available case types that can be used when creating or filtering cases.","responses":{"200":{"description":"List of available case types retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"string"},"description":"Array of available case types"}},"required":["data"]}}}}}}},"/cases/{id}/members":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List members of a case","description":"Returns every member of a case with user details (name, phone, email, language, profile image) and their organization role.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"responses":{"200":{"description":"Case members retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"case_phase":{"type":"string","nullable":true},"phase_id":{"type":"string","nullable":true},"phase_updated_at":{"type":"string","nullable":true},"allow_messages":{"type":"boolean"},"contactable":{"type":"boolean"},"invited_at":{"type":"string","nullable":true},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"profile_image":{"type":"string","nullable":true},"language_code":{"type":"string","nullable":true},"role":{"type":"string","nullable":true,"description":"The member's role in the organization"}},"required":["id","name","phone","email","profile_image","language_code","role"]}},"required":["id","user_id","status","case_phase","phase_id","phase_updated_at","allow_messages","contactable","invited_at","created_at","updated_at","user"]}}},"required":["case_id","members"]}},"required":["message","data"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Add members to a case","description":"Adds users as members of a case without sending any SMS invitations. Use POST /cases/{id}/invite if you want the SMS invite text to go out. Users already on the case, or users not in the org with a matching role, are NOT added and are returned in `data.skipped` with a reason (`already_member` / `not_org_member`) — check it to confirm staff actually landed. Clients are added with status `pending`.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","items":{"type":"string","description":"User ID"},"description":"User IDs to add as case members"},"role":{"type":"string","enum":["client","staff"],"description":"Role of the users being added"},"contactable":{"type":"boolean","description":"Whether the members' contact info is visible to clients (staff only; ignored for clients)"}},"required":["users","role"]},"examples":{"addClients":{"summary":"Add clients to a case (no SMS invite)","value":{"users":["7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","8c1f6d12-3b4a-4a9d-8f0c-1234567890ab"],"role":"client"}},"addContactableStaff":{"summary":"Add a staff member visible to clients (e.g. lead attorney)","value":{"users":["e1f2a3b4-c5d6-4789-9012-3456789abcde"],"role":"staff","contactable":true}}}}}},"responses":{"200":{"description":"Members added (or already present) on the case","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"members":{"type":"array","items":{"type":"object","properties":{"member_id":{"type":"string","description":"The case_members row ID"},"user_id":{"type":"string","nullable":true,"description":"The user ID of the member"},"status":{"type":"string","nullable":true,"description":"The member status on the case"}},"required":["member_id","user_id","status"]},"description":"Current members on the case after the add operation"},"skipped":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","description":"A requested user_id that was not added"},"reason":{"type":"string","enum":["already_member","not_org_member"],"description":"`already_member`: already on the case. `not_org_member`: the id is not a matching-role member of this organization — for staff, create them via POST /v2/staff first."}},"required":["user_id","reason"]},"description":"Requested user_ids that were NOT added, each with a reason. A non-empty `not_org_member` here is the usual cause of \"staff not appearing on the case\"."}},"required":["case_id","members","skipped"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Update a case member","description":"Updates `contactable` and/or `allow_messages` on a case member. `contactable` is silently ignored for client members — only staff members can be toggled contactable.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","description":"The user ID of the member to update"},"contactable":{"type":"boolean","description":"Whether the member's contact info is visible to clients"},"allow_messages":{"type":"boolean","description":"Whether the member can receive messages"}},"required":["user_id"]},"example":{"user_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","contactable":true,"allow_messages":true}}}},"responses":{"200":{"description":"Member updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"member":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"contactable":{"type":"boolean"},"allow_messages":{"type":"boolean"},"updated_at":{"type":"string","nullable":true}},"required":["id","user_id","status","contactable","allow_messages","updated_at"]}},"required":["case_id","member"]}},"required":["message","data"]}}}}}},"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Remove a member from a case","description":"Removes a user from a case. The user is still a member of the organization — only the case_members row is deleted.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","description":"The user ID of the member to remove"}},"required":["user_id"]},"example":{"user_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345"}}}},"responses":{"200":{"description":"Member removed from the case","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"removed_member":{"type":"object","properties":{"id":{"type":"string"},"user_id":{"type":"string","nullable":true}},"required":["id","user_id"]}},"required":["case_id","removed_member"]}},"required":["message","data"]}}}}}}},"/cases/{id}/phase":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Update case phase","description":"Updates the phase of a specific case, allowing progression through different stages of case workflow. Optionally updates the last modified timestamp and custom CMS data.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case to update"},"required":true,"description":"The unique identifier of the case to update","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"phase":{"type":"string","description":"The new phase for the case"},"updated_at":{"type":"string","description":"The date and time when the case was last updated (ISO 8601 format)"},"cms_data":{"nullable":true,"description":"Any additional custom data for the case"}},"required":["phase"]},"example":{"phase":"Discovery","updated_at":"2026-05-14T15:00:00.000Z"}}}},"responses":{"200":{"description":"Case phase updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"phase":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"cms_data":{"type":"object","nullable":true,"properties":{}}},"required":["id","phase","updated_at","cms_data"]}},"required":["message","data"]}}}}}}},"/cases/{id}/incident":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve a case's incident record","description":"Returns the incident attached to a case — the narrative (what happened before, during, and after), plus location, date, and time of injury. Returns `data: null` if no incident has been recorded. To structure raw narrative text into before/during/after, use POST /v2/incidents/structure first (separate utility endpoint).","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"responses":{"200":{"description":"Incident retrieved (may be null)","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"what_happened_before":{"type":"string","nullable":true},"what_happened_during":{"type":"string","nullable":true},"what_happened_after":{"type":"string","nullable":true},"incident_location":{"type":"string","nullable":true},"date_of_injury":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"time_of_injury":{"type":"string","nullable":true,"description":"HH:MM:SS"},"sketch_image":{"type":"array","nullable":true,"items":{"type":"string"}},"explanation_video":{"type":"array","nullable":true,"items":{"type":"string"}},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true}},"required":["id","case_id","what_happened_before","what_happened_during","what_happened_after","incident_location","date_of_injury","time_of_injury","sketch_image","explanation_video","created_at","updated_at"]}},"required":["message","data"]}}}}}},"put":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Upsert a case's incident record","description":"Creates or updates the incident record for a case. Accepts any subset of writable fields; missing fields are left unchanged (partial merge). Media fields (sketch_image, explanation_video) are read-only here — uploads go through the storage endpoints.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"what_happened_before":{"type":"string","description":"What happened leading up to the incident"},"what_happened_during":{"type":"string","description":"What happened during the incident itself"},"what_happened_after":{"type":"string","description":"What happened after the incident"},"incident_location":{"type":"string","description":"Free-text location of the incident"},"date_of_injury":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Date of injury in YYYY-MM-DD format"},"time_of_injury":{"type":"string","pattern":"^\\d{2}:\\d{2}(:\\d{2})?$","description":"Time of injury in HH:MM or HH:MM:SS format"}}},"example":{"before":"I was driving south on Main Street, heading home from work. Traffic was light and the road was dry.","during":"Another driver ran the red light at the Main and 5th intersection and struck the front-passenger side of my vehicle.","after":"Airbags deployed. I called 911 and waited for police and an ambulance. I was taken to the ER as a precaution.","incident_location":"Main St & 5th Ave, Springfield, IL"}}}},"responses":{"200":{"description":"Incident upserted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"what_happened_before":{"type":"string","nullable":true},"what_happened_during":{"type":"string","nullable":true},"what_happened_after":{"type":"string","nullable":true},"incident_location":{"type":"string","nullable":true},"date_of_injury":{"type":"string","nullable":true,"description":"YYYY-MM-DD"},"time_of_injury":{"type":"string","nullable":true,"description":"HH:MM:SS"},"sketch_image":{"type":"array","nullable":true,"items":{"type":"string"}},"explanation_video":{"type":"array","nullable":true,"items":{"type":"string"}},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true}},"required":["id","case_id","what_happened_before","what_happened_during","what_happened_after","incident_location","date_of_injury","time_of_injury","sketch_image","explanation_video","created_at","updated_at"]}},"required":["message","data"]}}}}}}},"/cases/{id}/injuries":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve a case's injuries by body part","description":"Returns the case's injuries organized by body part. Each entry uses a canonical Quilia body-part name (e.g. \"Right Knee\", laterality baked into the name) as the spine, with the AI-extracted detail, the providers the client mapped to treating that part, the pain history for that part (oldest first), and any injury photos nested under it. The body-part set is the union of every part referenced anywhere on the case, so nothing is dropped. Map the canonical names against your own predefined body parts. Returns empty arrays (not 404) when the case exists but has no injuries recorded.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"responses":{"200":{"description":"Injuries retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"injured_body_parts":{"type":"array","items":{"type":"string"},"description":"The body parts the client reported as injured."},"injuries":{"type":"array","items":{"type":"object","properties":{"body_part":{"type":"string","description":"Canonical Quilia body-part name, e.g. \"Right Knee\" (laterality is in the name). Map these against your own predefined body parts. Canonical values: Head, Face, Brain, Neck, Chest, Abdomen, Upper Back, Middle Back, Lower Back, Gluteus Maximus, Right Groin, Left Groin, Right Shoulder, Right Arm, Right Elbow, Right Forearm, Right Wrist, Right Hand, Left Shoulder, Left Arm, Left Elbow, Left Forearm, Left Wrist, Left Hand, Right Hip, Right Thigh, Right Knee, Right Lower Leg, Right Ankle, Right Foot, Left Hip, Left Thigh, Left Knee, Left Lower Leg, Left Ankle, Left Foot, Groin, Right Leg, Left Leg. A small number of legacy records may carry retired names outside this list."},"details":{"type":"object","nullable":true,"properties":{"type":{"type":"string","nullable":true,"description":"Nature of the injury, e.g. \"strain\", \"fracture\"."},"severity":{"type":"string","nullable":true,"description":"Reported severity, e.g. \"mild\", \"moderate\", \"severe\"."},"description":{"type":"string","nullable":true,"description":"Free-text description of the injury."}}},"providers":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","nullable":true},"treatment_status":{"type":"string","nullable":true,"description":"\"treating\" (active care), \"complete\" (released), or null."},"released_at":{"type":"string","nullable":true,"description":"When the client was released from this provider, if complete."}},"required":["name","treatment_status","released_at"]},"description":"Providers the client mapped to treating this body part."},"pain_history":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string","nullable":true,"description":"When the pain score was recorded (check-in timestamp)."},"score":{"type":"number","description":"Pain rating for this body part (typically 0–10)."}},"required":["date","score"]},"description":"Pain scores recorded for this body part over time, oldest first."},"photos":{"type":"array","items":{"type":"string"},"description":"Stored asset references for injury photos linked to this body part. Photos attach at the injury level, so a photo may span multiple body parts of the same injury."}},"required":["body_part","details","providers","pain_history","photos"]},"description":"One entry per injured body part, with that part as the spine: details, treating providers, pain history, and photos nested under it."}},"required":["case_id","injured_body_parts","injuries"]}},"required":["message","data"]}}}}}}},"/cases/{id}/damage":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve a case's damage record","description":"Returns the damage record attached to a case. Today's schema is vehicle-centric (year, make, model, VIN, color, trim, mileage, license plate, type); the endpoint is named generically to accommodate future non-vehicle damage (bikes, scooters, buses, eventually other property). Returns `data: null` if no damage has been recorded.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"responses":{"200":{"description":"Damage retrieved (may be null)","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"vehicle_year":{"type":"number","nullable":true},"vehicle_make":{"type":"string","nullable":true},"vehicle_model":{"type":"string","nullable":true},"vehicle_trim":{"type":"string","nullable":true},"vehicle_vin":{"type":"string","nullable":true},"vehicle_color":{"type":"string","nullable":true},"vehicle_mileage":{"type":"number","nullable":true},"vehicle_license_plate":{"type":"string","nullable":true},"vehicle_type":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"images":{"type":"array","nullable":true,"items":{"type":"string"}},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true}},"required":["id","case_id","vehicle_year","vehicle_make","vehicle_model","vehicle_trim","vehicle_vin","vehicle_color","vehicle_mileage","vehicle_license_plate","vehicle_type","notes","images","created_at","updated_at"]}},"required":["message","data"]}}}}}},"put":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Upsert a case's damage record","description":"Creates or updates the damage record for a case. Accepts any subset of writable fields; missing fields are left unchanged (partial merge). The `images` field is storage-managed and excluded from this endpoint — uploads go through the storage endpoints.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"vehicle_year":{"type":"integer"},"vehicle_make":{"type":"string"},"vehicle_model":{"type":"string"},"vehicle_trim":{"type":"string"},"vehicle_vin":{"type":"string"},"vehicle_color":{"type":"string"},"vehicle_mileage":{"type":"integer"},"vehicle_license_plate":{"type":"string"},"vehicle_type":{"type":"string"},"notes":{"type":"string"}}},"example":{"year":2022,"make":"Toyota","model":"Camry","color":"silver","trim":"SE","vin":"4T1G11AK4NU000000","license_plate":"ABC1234","mileage":34250,"type":"vehicle"}}}},"responses":{"200":{"description":"Damage upserted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"vehicle_year":{"type":"number","nullable":true},"vehicle_make":{"type":"string","nullable":true},"vehicle_model":{"type":"string","nullable":true},"vehicle_trim":{"type":"string","nullable":true},"vehicle_vin":{"type":"string","nullable":true},"vehicle_color":{"type":"string","nullable":true},"vehicle_mileage":{"type":"number","nullable":true},"vehicle_license_plate":{"type":"string","nullable":true},"vehicle_type":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"images":{"type":"array","nullable":true,"items":{"type":"string"}},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true}},"required":["id","case_id","vehicle_year","vehicle_make","vehicle_model","vehicle_trim","vehicle_vin","vehicle_color","vehicle_mileage","vehicle_license_plate","vehicle_type","notes","images","created_at","updated_at"]}},"required":["message","data"]}}}}}}},"/cases/{id}/insurance":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List a case's insurance policies","description":"Returns every insurance policy recorded on a case, newest first. A case commonly carries more than one — typically the client's own auto policy and their health coverage — so this always returns a list, never a single record.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"responses":{"200":{"description":"Insurance policies retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"insurance":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"external_id":{"type":"string","nullable":true,"description":"Your own id for this policy, echoed back so you can map our id to yours."},"type":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"policy_number":{"type":"string","nullable":true},"group_number":{"type":"string","nullable":true},"claim_number":{"type":"string","nullable":true},"insured_name":{"type":"string","nullable":true},"policy_owner":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"effective_date":{"type":"string","nullable":true},"expiration_date":{"type":"string","nullable":true},"copay":{"type":"string","nullable":true},"deductible":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true}},"required":["id","case_id","external_id","type","company","policy_number","group_number","claim_number","insured_name","policy_owner","phone","effective_date","expiration_date","copay","deductible","notes","created_at","updated_at"]}}},"required":["case_id","insurance"]}},"required":["message","data"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Add an insurance policy to a case","description":"Records an insurance policy on a case. Send one call per policy — a case normally has several, and the two that matter most on a personal injury case are the client's own auto policy (`type: \"First Party Car\"`) and their health coverage (`type: \"Health\"`).\n\n**Re-syncing is safe.** Send your own `external_id` on the policy and it becomes the match key: it is checked first, ahead of every rule below, and it matches on the case alone rather than the case and `type`, so correcting a policy's type still finds the row you wrote last night. Without one, a policy matching the same case, same `type`, and same `policy_number` is updated in place rather than duplicated; the response's `action` field tells you which happened.\n\nWhen you have no `policy_number`, the match falls back to the same case, same `type`, and same `company`, considering only policies that also have no number — so a re-sync still updates rather than duplicating, and it will never overwrite a policy whose number you have already sent. Send a `policy_number` whenever you hold one: it is the more precise key, and it is what lets a case carry two policies from the same carrier.\n\nOnly `type` is required, plus at least one of `external_id`, `company`, `policy_number`, `claim_number` or `insured_name` so the policy can be told apart from the others on the case. Everything else is optional, so send whatever subset you hold — a claim number with no carrier yet is a policy worth recording.\n\n**Send `type` in your own vocabulary.** We map it rather than rejecting it: `Auto` is recorded as `First Party Car` (this endpoint records your client's own policies, so send `Other Party Car` explicitly for the adverse carrier), `WC` as `Workers Compensation`, `Home` as `Homeowner`. A label we cannot place is recorded as `Other` so the carrier, policy number and claim number still land. The `type` in the response is what was stored.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"external_id":{"type":"string","minLength":1,"description":"Your own id for this policy. The match key: send it and a repeat call updates the policy instead of creating a second one. Unique per case, and it beats every other match rule below."},"type":{"type":"string","description":"The kind of policy. Send your own label and we map it: \"Auto\" becomes \"First Party Car\", \"WC\" becomes \"Workers Compensation\", and anything we can't place is recorded as \"Other\" rather than failing the call. The response shows what was stored. Our vocabulary is: First Party Car, Other Party Car, Health, Company Car, Homeowner, Renter, Umbrella, Disability, Life, Medicare/Medicaid, Travel, Workers Compensation, Other."},"company":{"type":"string","description":"Carrier name. Optional: send the policy with just a claim or policy number when you do not have the carrier yet."},"policy_number":{"anyOf":[{"type":"string"},{"type":"number"}]},"group_number":{"anyOf":[{"type":"string"},{"type":"number"}]},"claim_number":{"anyOf":[{"type":"string"},{"type":"number"}]},"insured_name":{"type":"string","description":"Name of the insured, when it is not the client"},"policy_owner":{"type":"string"},"phone":{"anyOf":[{"type":"string"},{"type":"number"}],"description":"The carrier's phone number"},"effective_date":{"type":"string"},"expiration_date":{"type":"string"},"copay":{"anyOf":[{"type":"string"},{"type":"number"}]},"deductible":{"anyOf":[{"type":"string"},{"type":"number"}]},"notes":{"type":"string"}},"required":["type"]},"examples":{"firstPartyAuto":{"summary":"The client's own auto policy","value":{"type":"First Party Car","company":"State Farm","policy_number":"SF-4471902","claim_number":"77-9921-C","phone":"+18005551000","deductible":"500"}},"health":{"summary":"The client's health coverage","value":{"type":"Health","company":"Blue Cross Blue Shield","policy_number":"BCBS-88213004","group_number":"GRP-10052","insured_name":"Jane Doe","copay":"25"}}}}}},"responses":{"200":{"description":"Insurance policy recorded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"external_id":{"type":"string","nullable":true,"description":"Your own id for this policy, echoed back so you can map our id to yours."},"type":{"type":"string","nullable":true},"company":{"type":"string","nullable":true},"policy_number":{"type":"string","nullable":true},"group_number":{"type":"string","nullable":true},"claim_number":{"type":"string","nullable":true},"insured_name":{"type":"string","nullable":true},"policy_owner":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"effective_date":{"type":"string","nullable":true},"expiration_date":{"type":"string","nullable":true},"copay":{"type":"string","nullable":true},"deductible":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"action":{"type":"string","enum":["created","updated"],"description":"Whether a new policy was written or an existing one was matched and updated. See the endpoint description for the match rule."}},"required":["id","case_id","external_id","type","company","policy_number","group_number","claim_number","insured_name","policy_owner","phone","effective_date","expiration_date","copay","deductible","notes","created_at","updated_at","action"]}},"required":["message","data"]}}}}}}},"/cases/{id}/providers":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Create a provider on a case","description":"Records a medical provider (or other care entity) on a case. The endpoint attempts to auto-link the new person row to an existing `providers_list` master entry by normalized name + phone/fax match. When the match is confident it returns `matched: true` with a `provider_list_id`; otherwise `matched: false` and the row is left unlinked for a human to reconcile later. The endpoint does not create new `providers_list` rows — external input only extends the case-scoped `people` table. Supply `external_id` to make repeated calls idempotent.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"Provider name (required). This is the only name field — a provider row carries one name, whether it is a person or a facility. Send the full name here; use `other_names` for aliases or a DBA."},"other_names":{"type":"array","items":{"type":"string"}},"address_1":{"type":"string"},"address_2":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string"},"phone":{"type":"string"},"fax":{"type":"string"},"email":{"type":"string"},"website":{"type":"string"},"domain":{"type":"string"},"specialty":{"type":"string"},"external_id":{"type":"string","description":"Identifier from the calling integration (e.g., the provider's ID in Ethos / Filevine / another CMS). Stored in metadata.external_id. If a later call reuses the same external_id on the same case, the existing row is updated instead of a duplicate being created."}},"required":["name"]},"example":{"name":"Mercy General Hospital","phone":"+15555550150","fax":"+15555550151","address_1":"123 Main St","city":"Springfield","state":"IL","postal_code":"62701","external_id":"CMS-PROVIDER-789"}}}},"responses":{"200":{"description":"Provider upserted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"person_id":{"type":"string","description":"The public.people row id for this case"},"case_id":{"type":"string"},"provider_list_id":{"type":"string","nullable":true,"description":"The providers_list row this person was matched to, or null if no confident match. Unmatched rows can be linked later by a human."},"matched":{"type":"boolean","description":"Whether a providers_list match was found with high confidence"},"action":{"type":"string","enum":["created","updated"],"description":"Whether the people row was created or an existing one updated"}},"required":["person_id","case_id","provider_list_id","matched","action"]}},"required":["message","data"]}}}}}}},"/cases/{id}/feed":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve a case activity feed","description":"Returns the activity feed scoped to a single case — client uploads, messages, appointments, and case updates in chronological order. Same time-range params as the org feed (days / hours / start / end; default last 24h). This is the natural 'what's happening on this case?' read.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The case id"},"required":true,"description":"The case id","name":"id","in":"path"},{"schema":{"type":"number","minimum":0,"exclusiveMinimum":true,"description":"Days to include (> 0). Takes precedence over hours."},"required":false,"description":"Days to include (> 0). Takes precedence over hours.","name":"days","in":"query"},{"schema":{"type":"number","minimum":0,"exclusiveMinimum":true,"description":"Hours to include (> 0). Default 24 if neither is given."},"required":false,"description":"Hours to include (> 0). Default 24 if neither is given.","name":"hours","in":"query"},{"schema":{"type":"string","description":"Start date (ISO 8601)","example":"2026-05-01T00:00:00Z"},"required":false,"description":"Start date (ISO 8601)","name":"start","in":"query"},{"schema":{"type":"string","description":"End date (ISO 8601)","example":"2026-05-29T23:59:59Z"},"required":false,"description":"End date (ISO 8601)","name":"end","in":"query"}],"responses":{"200":{"description":"Case feed retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"case_id":{"type":"string","nullable":true},"case_member_id":{"type":"string","nullable":true},"logs_data":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"action":{"type":"string"},"log_id":{"type":"string"},"metadata":{"type":"object","properties":{}},"timezone":{"type":"string"},"created_at":{"type":"string"},"attachments":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"fileType":{"type":"string"},"filename":{"type":"string"}},"required":["url","fileType","filename"]}},"description":{"type":"string"}},"required":["title","action","log_id","metadata","timezone","created_at","attachments","description"]}}},"required":["user_id","case_id","case_member_id","logs_data"],"description":"Array of feed entries grouped by user and case"}}},"required":["message","data"]}}}}}}},"/cases/{id}/summary":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve a case summary","description":"The case's living summary — a concise, always-current AI digest of the matter, the way a sharp case manager holds it in their head. It is regenerated from source whenever the underlying case data changes, structured around the Liability / Coverage / Damages pillars, and includes what's been done and what the case still needs. Read this for an instant, framed picture of a case before acting on it. `data` is null when the case exists but has no summary yet (a brand-new or quiet case that hasn't been summarized).","parameters":[{"schema":{"type":"string","description":"The case id"},"required":true,"description":"The case id","name":"id","in":"path"}],"responses":{"200":{"description":"Case summary retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","nullable":true,"properties":{"case_id":{"type":"string"},"user_id":{"type":"string","nullable":true,"description":"The case member the summary is stored on (the case representative — usually the primary client). One summary per case."},"summary":{"type":"string","nullable":true,"description":"The current human-readable case summary (prose)."},"structured":{"type":"object","nullable":true,"properties":{},"description":"The machine-readable digest parsed from the same generation (phase, assessment [array of {pillar, read}], client_actions, firm_actions, open_questions, risk_flags, engagement)."},"model":{"type":"string","nullable":true,"description":"The model that generated the current summary."},"updated_at":{"type":"string","nullable":true,"description":"When the summary was last rebuilt (ISO 8601)."}},"required":["case_id","user_id","summary","structured","model","updated_at"]}},"required":["message","data"]}}}}}}},"/cases/{id}/documents":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List a case's documents","description":"Returns every document (asset) on a case with its per-document \"case-manager memo\" — a 1–2 sentence note of what matters in that document (e.g. a lab result's finding, a record's key facts) — and `text`, the text the analyzer read out of the document. This is the fast way to load granular per-document context for a case. `memo` and `text` are null for a document that hasn't been analyzed yet, and `text` is also null when the document had no text in it (a scene photo, an audio clip); `with_memo` and `with_text` count how many have each.","parameters":[{"schema":{"type":"string","description":"The case id"},"required":true,"description":"The case id","name":"id","in":"path"}],"responses":{"200":{"description":"Case documents retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"total":{"type":"number"},"with_memo":{"type":"number","description":"How many documents have a memo"},"with_text":{"type":"number","description":"How many documents have extracted text on them"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string","nullable":true},"label":{"type":"string","nullable":true,"description":"The document/asset label (e.g. \"lab result\", \"medical record\")"},"description":{"type":"string","nullable":true},"analysis_status":{"type":"string","nullable":true,"description":"AI analysis status (e.g. \"completed\", \"pending\")"},"memo":{"type":"string","nullable":true,"description":"The per-document case-manager memo — a 1–2 sentence note of what matters in this document. Null if not analyzed/memo'd yet."},"text":{"type":"string","nullable":true,"description":"The text the analyzer read out of this document. Null if the document hasn't been analyzed yet, or if there was no text in it (a scene photo, an audio clip). This is what the analyzer captured, not a guaranteed full transcription — long documents may be condensed."},"created_at":{"type":"string","nullable":true}},"required":["id","filename","label","description","analysis_status","memo","text","created_at"]}}},"required":["case_id","total","with_memo","with_text","documents"]}},"required":["message","data"]}}}}}}},"/cases/{id}/notes":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List a case's notes","description":"Returns the notes on a case (the client-authored \"attorney updates\" — what the client has written in to the firm), newest first. Read-only: notes are written by clients, not the firm/API. Read these for the client's own running account of the case.","parameters":[{"schema":{"type":"string","description":"The case id"},"required":true,"description":"The case id","name":"id","in":"path"}],"responses":{"200":{"description":"Case notes retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"total":{"type":"number"},"notes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"notes":{"type":"string","nullable":true,"description":"The note body (client-authored)."},"prompt_topic":{"type":"string","nullable":true,"description":"The topic/prompt the note was written against, if any."},"created_by":{"type":"string","nullable":true},"created_at":{"type":"string","nullable":true}},"required":["id","notes","prompt_topic","created_by","created_at"]}}},"required":["case_id","total","notes"]}},"required":["message","data"]}}}}}}},"/cases/{id}/sources/{ref}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Resolve one case-memory source reference","description":"Returns the single source row a case-memory citation points at, in full. `ref` is the reference as it appears in the memory's structured `sources` (e.g. \"hc:1a2b3c4d\"): a short code for the table plus the first 8 characters of the row id. Codes are hc (health check-in), cn (case note), cc (CaseChat message) and ca (a check-in ask the client answered without entering data). The reference is resolved WITHIN the case, so an unknown or cross-case reference reads as not found rather than reaching another case's row.","parameters":[{"schema":{"type":"string","description":"The case id"},"required":true,"description":"The case id","name":"id","in":"path"},{"schema":{"type":"string","description":"The source reference from the memory, e.g. \"hc:1a2b3c4d\""},"required":true,"description":"The source reference from the memory, e.g. \"hc:1a2b3c4d\"","name":"ref","in":"path"}],"responses":{"200":{"description":"Source record retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"ref":{"type":"string","description":"The reference as it appeared in the memory, e.g. \"hc:1a2b3c4d\"."},"table":{"type":"string","description":"The table the reference resolved to, e.g. \"public.pain_scores\"."},"case_id":{"type":"string"},"record":{"type":"object","additionalProperties":{"nullable":true},"description":"The source row in full, in the shape of its own table."}},"required":["ref","table","case_id","record"]}},"required":["message","data"]}}}}}}},"/cases/{id}/contacts":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List contacts attached to a case","description":"Returns every contact attached to a case, split into `people` and `companies` buckets. Use the optional `kind` query parameter to limit results to one bucket. Use the optional `contact_type` parameter to filter by category (e.g. `witness`, `police department`).\n\nReturns 400 if the combination is impossible — e.g. `kind=company` with `contact_type=witness`, since 'witness' is only valid for people contacts.\n\nReturns empty arrays (not 404) when the case exists but has no contacts.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"},{"schema":{"type":"string","enum":["people","company"],"description":"Limit results to one bucket. Omit to return both. Use 'people' for personal contacts (witness, emergency contact, etc.) or 'company' for company contacts (insurance company, body shop, etc.)."},"required":false,"description":"Limit results to one bucket. Omit to return both. Use 'people' for personal contacts (witness, emergency contact, etc.) or 'company' for company contacts (insurance company, body shop, etc.).","name":"kind","in":"query"},{"schema":{"type":"string","enum":["witness","adjustor","provider","emergency contact","supervisor","ambulance","emergency room","other driver","body shop","medical provider","rental company","police department","employer","insurance company","law firm","towing company","vehicle storage"],"description":"Filter by contact category. Must be valid for the selected kind (or for either kind if `kind` is omitted)."},"required":false,"description":"Filter by contact category. Must be valid for the selected kind (or for either kind if `kind` is omitted).","name":"contact_type","in":"query"}],"responses":{"200":{"description":"Contacts retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"people":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"user_id":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"address_1":{"type":"string","nullable":true},"address_2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"relationship":{"type":"string","nullable":true},"treatment_status":{"type":"string","nullable":true,"description":"For provider contacts: \"treating\" (active care), \"complete\" (released), or null. Tracks where the client is in treatment."},"created_at":{"type":"string","nullable":true}},"required":["id","case_id","user_id","email","phone","name","address_1","address_2","city","state","postal_code","country","type","relationship","treatment_status","created_at"]}},"companies":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string","nullable":true},"user_id":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"address_1":{"type":"string","nullable":true},"address_2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"police_report_number":{"type":"string","nullable":true},"created_at":{"type":"string","nullable":true}},"required":["id","case_id","user_id","name","phone","address_1","address_2","city","state","postal_code","country","type","police_report_number","created_at"]}}},"required":["case_id","people","companies"]}},"required":["message","data"]}}}}}}},"/cases/{id}/contacts/{contact_id}":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Update a contact's treatment status","description":"Set a provider contact's treatment status for the case. \"complete\" marks the client released from that provider and stamps `released_at` to now; \"treating\" marks active care and clears `released_at`. Use this to track where the client is in treatment (the basis for no-next-appointment re-engagement).","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"},{"schema":{"type":"string","description":"The contact (people row) id to update"},"required":true,"description":"The contact (people row) id to update","name":"contact_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"treatment_status":{"type":"string","enum":["treating","complete"],"description":"Set \"treating\" for active care or \"complete\" to release the client (stamps released_at to now)."}},"required":["treatment_status"]}}}},"responses":{"200":{"description":"Treatment status updated","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"treatment_status":{"type":"string","nullable":true},"released_at":{"type":"string","nullable":true}},"required":["id","name","type","treatment_status","released_at"]}},"required":["message","data"]}}}}}}},"/cases/{id}/employments":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Create an employment record on a case","description":"Creates an employment relationship for a case member, tying a client to an employer company and optional supervisor in the context of a specific case.\n\n**The short form is one call.** Send `company_name` and `job_title` and nothing else: the employer company is resolved on this case by name (case-insensitive) or created, and `user_id` defaults to the case's primary client. No `POST /v2/contacts` round trip to mint an id first.\n\n**Re-syncing is safe when you send `external_id`.** It is your own id for the employment and the match key: a repeat call with the same one on the same case updates that employment in place rather than creating a second, and only the fields you send are changed. Omit it and every call creates a new record.\n\nSend `company_id` instead when you already hold one — it wins over `company_name`. Send `user_id` explicitly on a case with several clients. Supervisors are still contacts: create one via `POST /v2/contacts` and pass `supervisor_id`.\n\n**Validation**:\n- `case_id` (from path) must belong to the authenticated organization.\n- `user_id`, given or defaulted, must be a member of this case (not just the organization).\n- `company_id`, if provided, must belong to the organization.\n- `supervisor_id`, if provided, must belong to the organization.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"external_id":{"type":"string","minLength":1,"description":"Your own id for this employment. The match key: send it and a repeat call updates the employment instead of creating a second one. Unique per case."},"user_id":{"type":"string","format":"uuid","description":"The client (case member) this employment is for. Defaults to the case's primary client, so only send it for a case with several clients."},"company_id":{"type":"string","format":"uuid","description":"The employer company (a `companies` row, typically with `type: 'employer'`). Send `company_name` instead if you only have the name."},"company_name":{"type":"string","minLength":1,"description":"The employer's name. Resolves to an existing employer company on this case (case-insensitive) or creates one, so you do not need a POST /v2/contacts call first. Ignored when `company_id` is given."},"job_title":{"type":"string","description":"Job title at this employer"},"supervisor_id":{"type":"string","format":"uuid","description":"Optional — the supervisor person (a `people` row, typically with `type: 'supervisor'`)"},"is_primary":{"type":"boolean","description":"Whether this is the client's primary employment for the case. Defaults to false. Multiple primaries per case are allowed (not enforced here)."}}},"examples":{"byName":{"summary":"Short form — employer name only (one call)","value":{"company_name":"Acme Corporation","job_title":"Delivery Driver","is_primary":true}},"byId":{"summary":"Existing company and supervisor contacts, by id","value":{"user_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","company_id":"b1c2d3e4-f5a6-4789-9bcd-ef0123456789","supervisor_id":"a1b2c3d4-e5f6-4789-9abc-def012345678","job_title":"Delivery Driver","is_primary":true}}}}}},"responses":{"200":{"description":"Employment created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this employment, echoed back so you can map our id to yours."},"user_id":{"type":"string"},"company_id":{"type":"string","nullable":true},"job_title":{"type":"string","nullable":true},"supervisor_id":{"type":"string","nullable":true},"is_primary":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"company":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"address_1":{"type":"string","nullable":true},"address_2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","nullable":true}},"required":["id","name","type","phone","address_1","address_2","city","state","postal_code","country"]},"supervisor":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true}},"required":["id","name","type","phone","email"]}},"required":["id","case_id","external_id","user_id","company_id","job_title","supervisor_id","is_primary","created_at","updated_at","company","supervisor"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"List employments on a case","description":"Returns every employment record on a case, sorted primary first. Each row includes the joined employer company and supervisor person where present.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"}],"responses":{"200":{"description":"Employments retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_id":{"type":"string"},"employments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this employment, echoed back so you can map our id to yours."},"user_id":{"type":"string"},"company_id":{"type":"string","nullable":true},"job_title":{"type":"string","nullable":true},"supervisor_id":{"type":"string","nullable":true},"is_primary":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"company":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"address_1":{"type":"string","nullable":true},"address_2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","nullable":true}},"required":["id","name","type","phone","address_1","address_2","city","state","postal_code","country"]},"supervisor":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true}},"required":["id","name","type","phone","email"]}},"required":["id","case_id","external_id","user_id","company_id","job_title","supervisor_id","is_primary","created_at","updated_at","company","supervisor"]}}},"required":["case_id","employments"]}},"required":["message","data"]}}}}}}},"/cases/{id}/employments/{employmentId}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Retrieve a single employment record","description":"Returns a specific employment row with joined company and supervisor.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"},{"schema":{"type":"string","description":"The employment record ID"},"required":true,"description":"The employment record ID","name":"employmentId","in":"path"}],"responses":{"200":{"description":"Employment retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this employment, echoed back so you can map our id to yours."},"user_id":{"type":"string"},"company_id":{"type":"string","nullable":true},"job_title":{"type":"string","nullable":true},"supervisor_id":{"type":"string","nullable":true},"is_primary":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"company":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"address_1":{"type":"string","nullable":true},"address_2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","nullable":true}},"required":["id","name","type","phone","address_1","address_2","city","state","postal_code","country"]},"supervisor":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true}},"required":["id","name","type","phone","email"]}},"required":["id","case_id","external_id","user_id","company_id","job_title","supervisor_id","is_primary","created_at","updated_at","company","supervisor"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Update an employment record","description":"Updates an employment record. Only provided fields are replaced. `user_id` is immutable — to change the client, delete this employment and create a new one.\n\n`company_id` and `supervisor_id`, if provided, are validated against the organization to prevent cross-org leaks.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"},{"schema":{"type":"string","description":"The employment record ID"},"required":true,"description":"The employment record ID","name":"employmentId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"company_id":{"type":"string","format":"uuid"},"job_title":{"type":"string"},"supervisor_id":{"type":"string","format":"uuid"},"is_primary":{"type":"boolean"}}},"example":{"job_title":"Senior Delivery Driver","is_primary":true,"supervisor_id":"a1b2c3d4-e5f6-4789-9abc-def012345678"}}}},"responses":{"200":{"description":"Employment updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"case_id":{"type":"string"},"external_id":{"type":"string","nullable":true,"description":"Your own id for this employment, echoed back so you can map our id to yours."},"user_id":{"type":"string"},"company_id":{"type":"string","nullable":true},"job_title":{"type":"string","nullable":true},"supervisor_id":{"type":"string","nullable":true},"is_primary":{"type":"boolean"},"created_at":{"type":"string","nullable":true},"updated_at":{"type":"string","nullable":true},"company":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"address_1":{"type":"string","nullable":true},"address_2":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true},"country":{"type":"string","nullable":true}},"required":["id","name","type","phone","address_1","address_2","city","state","postal_code","country"]},"supervisor":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"type":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true}},"required":["id","name","type","phone","email"]}},"required":["id","case_id","external_id","user_id","company_id","job_title","supervisor_id","is_primary","created_at","updated_at","company","supervisor"]}},"required":["message","data"]}}}}}},"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["cases"],"summary":"Delete an employment record","description":"Deletes an employment record from a case. Returns 409 Conflict if the employment has `missed_times` rows attached — partners must delete those first to avoid silently losing time-loss claim data.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the case"},"required":true,"description":"The unique identifier of the case","name":"id","in":"path"},{"schema":{"type":"string","description":"The employment record ID"},"required":true,"description":"The employment record ID","name":"employmentId","in":"path"}],"responses":{"200":{"description":"Employment deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/case-types":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["case-types"],"summary":"List the firm's case types","description":"Returns every case type in the Quilia catalog with the firm's configuration for it, grouped by Areas of Law category. A case type the firm has never configured is reported with `configured: false` and its catalog default. Existing case types default on; opt-in practice areas such as probate default off.","responses":{"200":{"description":"Case types retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"enabled_count":{"type":"number","description":"How many case types the firm has enabled in total"},"total":{"type":"number","description":"How many case types exist in the catalog"},"categories":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string","description":"The Areas of Law category name"},"enabled_count":{"type":"number","description":"How many case types in this category are enabled"},"total":{"type":"number","description":"How many case types this category holds"},"case_types":{"type":"array","items":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether the firm uses this case type"},"is_default":{"type":"boolean","description":"Use this case type as the fallback configuration for any case type without its own"},"inactive_reminders_enabled":{"type":"boolean","description":"Send a reminder to clients on this case type who haven't opened the app in 7 days"},"ssn_enabled":{"type":"boolean","description":"Show clients on this case type a Social Security Number field in their profile"},"journal_prompts_enabled":{"type":"boolean","description":"Show clients on this case type AI follow-up prompts on the journal screen"},"case_type":{"type":"string","description":"The case type identifier, e.g. \"motor vehicle collision\""},"name":{"type":"string","description":"The display name, e.g. \"Motor Vehicle Collision\""},"category":{"type":"string","description":"The Areas of Law category, e.g. \"Personal Injury\""},"configured":{"type":"boolean","description":"Whether the firm has saved a configuration for this case type. When false, the values shown are the defaults that apply until it does."},"settings_url":{"type":"string","description":"Portal link for the settings this API does not cover: per-screen feature visibility, required documents, and request templates"}},"required":["case_type","name","category","configured","settings_url"]}}},"required":["category","enabled_count","total","case_types"]}},"uncatalogued_in_use":{"type":"array","items":{"type":"object","properties":{"case_type":{"type":"string"},"case_count":{"type":"number"}},"required":["case_type","case_count"]},"description":"Case types assigned to active cases that are not in the Quilia catalog. These cannot be enabled or disabled here, only remapped in the CMS."}},"required":["enabled_count","total","categories"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["case-types"],"summary":"Configure the firm's case types","description":"Turns case types on or off and sets their per-type options. Target one case type, several, or an entire Areas of Law category with `category` — disabling the 20 types a firm never files is one call, not twenty. Only the options you send are changed; the rest keep their current values. A case type with no saved configuration is created on first write. `is_default` may only be set when targeting exactly one case type, since a firm has one fallback. Requires an admin role.","requestBody":{"required":true,"description":"Which case types to configure, and what to set on them","content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether the firm uses this case type"},"is_default":{"type":"boolean","description":"Use this case type as the fallback configuration for any case type without its own"},"inactive_reminders_enabled":{"type":"boolean","description":"Send a reminder to clients on this case type who haven't opened the app in 7 days"},"ssn_enabled":{"type":"boolean","description":"Show clients on this case type a Social Security Number field in their profile"},"journal_prompts_enabled":{"type":"boolean","description":"Show clients on this case type AI follow-up prompts on the journal screen"},"case_types":{"type":"array","items":{"type":"string"},"minItems":1,"description":"The case types to configure. Provide this or `category`, not both."},"category":{"type":"string","description":"Configure every case type in this Areas of Law category, e.g. \"Immigration\". Provide this or `case_types`, not both."}}},"examples":{"disableCategory":{"summary":"Turn off every Immigration case type","value":{"category":"Immigration","enabled":false}},"keepOnlyWhatTheFirmRuns":{"summary":"Turn on the handful a firm actually files","value":{"case_types":["motor vehicle collision","premises liability","wrongful death"],"enabled":true}},"perTypeOptions":{"summary":"Set the options on one case type","value":{"case_types":["workers compensation"],"ssn_enabled":true,"inactive_reminders_enabled":true,"is_default":true}}}}}},"responses":{"200":{"description":"Case types configured successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"updated":{"type":"number","description":"How many case type configurations were written"},"case_types":{"type":"array","items":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether the firm uses this case type"},"is_default":{"type":"boolean","description":"Use this case type as the fallback configuration for any case type without its own"},"inactive_reminders_enabled":{"type":"boolean","description":"Send a reminder to clients on this case type who haven't opened the app in 7 days"},"ssn_enabled":{"type":"boolean","description":"Show clients on this case type a Social Security Number field in their profile"},"journal_prompts_enabled":{"type":"boolean","description":"Show clients on this case type AI follow-up prompts on the journal screen"},"case_type":{"type":"string","description":"The case type identifier, e.g. \"motor vehicle collision\""},"name":{"type":"string","description":"The display name, e.g. \"Motor Vehicle Collision\""},"category":{"type":"string","description":"The Areas of Law category, e.g. \"Personal Injury\""},"configured":{"type":"boolean","description":"Whether the firm has saved a configuration for this case type. When false, the values shown are the defaults that apply until it does."},"settings_url":{"type":"string","description":"Portal link for the settings this API does not cover: per-screen feature visibility, required documents, and request templates"}},"required":["case_type","name","category","configured","settings_url"]}}},"required":["updated","case_types"]}},"required":["message","data"]}}}}}}},"/case-types/symptoms":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["case-types"],"summary":"List the firm's symptom vocabulary","description":"Lists the symptoms available to the caller's firm: shared Quilia symptoms plus active firm-owned symptoms. When `case_type` is provided, each symptom indicates whether it is explicitly selected for that case type. Requires Custom Symptoms to be enabled and an admin role.","parameters":[{"schema":{"type":"string","description":"Optional case type identifier. When provided, selected_for_case_type is populated."},"required":false,"description":"Optional case type identifier. When provided, selected_for_case_type is populated.","name":"case_type","in":"query"},{"schema":{"type":"string","description":"Include symptoms hidden by this firm"},"required":false,"description":"Include symptoms hidden by this firm","name":"include_hidden","in":"query"}],"responses":{"200":{"description":"Symptoms retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"custom_symptoms_enabled":{"type":"boolean"},"case_type":{"type":"string","nullable":true},"selected_count":{"type":"number"},"symptoms":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable symptom key used by the app"},"label":{"type":"string","description":"Client-facing symptom label"},"category":{"type":"string","description":"Symptom category"},"source":{"type":"string","enum":["quilia","firm"],"description":"Whether this is a shared Quilia symptom or firm-owned"},"hidden":{"type":"boolean","description":"Whether the firm has hidden this symptom from pickers"},"global_case_types":{"type":"array","items":{"type":"string"},"description":"Case types this symptom applies to by Quilia default"},"firm_case_types":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Case types explicitly selected by this firm. Null means the firm uses the global default."},"selected_for_case_type":{"type":"boolean"}},"required":["key","label","category","source","hidden","global_case_types","firm_case_types"]}}},"required":["custom_symptoms_enabled","case_type","selected_count","symptoms"]}},"required":["message","data"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["case-types"],"summary":"Add firm-owned symptoms","description":"Adds symptoms owned by this firm. Shared Quilia symptoms are not edited. Re-adding a previously removed firm symptom reactivates it. Requires Custom Symptoms to be enabled and an admin role.","requestBody":{"required":true,"description":"Symptoms to add to the firm vocabulary","content":{"application/json":{"schema":{"type":"object","properties":{"symptoms":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","minLength":1,"maxLength":200,"description":"Client-facing symptom label"},"category":{"type":"string","enum":["physical","cognitive","emotional","ptsd"],"description":"Symptom category"}},"required":["label","category"]},"minItems":1,"maxItems":200}},"required":["symptoms"]},"examples":{"carbonMonoxide":{"summary":"Add carbon monoxide symptoms","value":{"symptoms":[{"label":"Lightheadedness","category":"physical"},{"label":"Memory gaps","category":"cognitive"}]}}}}}},"responses":{"200":{"description":"Firm symptoms added successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"requested":{"type":"number"},"added":{"type":"number"},"symptoms":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable symptom key used by the app"},"label":{"type":"string","description":"Client-facing symptom label"},"category":{"type":"string","description":"Symptom category"},"source":{"type":"string","enum":["quilia","firm"],"description":"Whether this is a shared Quilia symptom or firm-owned"},"hidden":{"type":"boolean","description":"Whether the firm has hidden this symptom from pickers"},"global_case_types":{"type":"array","items":{"type":"string"},"description":"Case types this symptom applies to by Quilia default"},"firm_case_types":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Case types explicitly selected by this firm. Null means the firm uses the global default."}},"required":["key","label","category","source","hidden","global_case_types","firm_case_types"]}}},"required":["requested","added","symptoms"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["case-types"],"summary":"Configure a case type's symptom picker","description":"Sets the complete symptom key list clients should see for one case type. Send an empty list to clear the custom case-type list and fall back to the firm's normal symptom list. Unknown or hidden symptom keys are ignored and reported. Requires Custom Symptoms to be enabled and an admin role.","requestBody":{"required":true,"description":"Case type and complete selected symptom key list","content":{"application/json":{"schema":{"type":"object","properties":{"case_type":{"type":"string","minLength":1,"description":"Case type identifier, e.g. \"carbon monoxide poisoning\""},"symptom_keys":{"type":"array","items":{"type":"string","minLength":1},"description":"The complete list of symptom keys to show for this case type. Send [] to clear the custom case-type list and fall back to the firm symptom list."}},"required":["case_type","symptom_keys"]},"examples":{"carbonMonoxide":{"summary":"Set carbon monoxide symptoms","value":{"case_type":"carbon monoxide poisoning","symptom_keys":["headaches","dizziness","brain_fog"]}}}}}},"responses":{"200":{"description":"Case type symptom settings saved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"case_type":{"type":"string"},"selected_count":{"type":"number"},"selected_symptom_keys":{"type":"array","items":{"type":"string"}},"hidden_symptom_keys":{"type":"array","items":{"type":"string"}},"unknown_symptom_keys":{"type":"array","items":{"type":"string"}}},"required":["case_type","selected_count","selected_symptom_keys","hidden_symptom_keys","unknown_symptom_keys"]}},"required":["message","data"]}}}}}}},"/clients":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"Create a new client","description":"Creates a new client record in the system with comprehensive contact information including name, phone, email, address, and demographic details. Phone number validation ensures proper formatting.","requestBody":{"required":true,"description":"Client creation data","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The name of the client"},"name_first":{"type":"string","description":"The first name of the client"},"name_last":{"type":"string","description":"The last name of the client"},"phone":{"type":"string","description":"The phone number of the client"},"language_code":{"type":"string","description":"The language code of the client"},"email":{"type":"string","format":"email","description":"The email of the client"},"address_1":{"type":"string","description":"The first line of the address"},"address_2":{"type":"string","description":"The second line of the address"},"city":{"type":"string","description":"The city"},"state":{"type":"string","description":"The state or province"},"postal_code":{"type":"string","description":"The postal code"},"country":{"type":"string","description":"The country"},"date_of_birth":{"type":"string","description":"The date of birth in YYYY-MM-DD format"}},"required":["name","phone"]},"example":{"name":"Jane Doe","name_first":"Jane","name_last":"Doe","phone":"+15551234567","email":"jane.doe@example.com","language_code":"en","address_1":"123 Main St","city":"Springfield","state":"IL","postal_code":"62701","country":"US","date_of_birth":"1985-06-15"}}}},"responses":{"200":{"description":"Client created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the creation operation"},"data":{"type":"object","properties":{"user_id":{"type":"string","nullable":true,"description":"The unique identifier of the created client"}},"required":["user_id"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"List clients","description":"Retrieves a paginated list of clients for the authenticated organization.\n\n## Additional Fields\n\nUse `?fields=` to include: address_1, address_2, city, state, postal_code, country, date_of_birth, language, timezone\n\n## Filtering\n\nUse `filter[field]=value` query parameters:\n\n- `filter[name]` - Full name\n- `filter[name_first]` - First name\n- `filter[name_last]` - Last name\n- `filter[email]` - Email address\n- `filter[phone]` - Phone number\n\n**Partial matching**: All filters match substrings by default (e.g., `john` matches \"Johnny\").\nUse `*` for explicit wildcard placement (e.g., `john*` for \"starts with\").\n\n**Multiple values**: Comma-separated for OR matching (exact match).\n\nNote: Combining wildcards with commas is not supported.","parameters":[{"schema":{"type":"number","nullable":true,"minimum":0,"default":10,"description":"The maximum number of clients to return."},"required":false,"description":"The maximum number of clients to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"The number of clients to skip before starting to return results."},"required":false,"description":"The number of clients to skip before starting to return results.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of additional fields to include. Available: address_1, address_2, city, state, postal_code, country, date_of_birth, language, timezone"},"required":false,"description":"Comma-separated list of additional fields to include. Available: address_1, address_2, city, state, postal_code, country, date_of_birth, language, timezone","name":"fields","in":"query"},{"schema":{"type":"string","description":"Filter by name. See endpoint description for syntax."},"required":false,"description":"Filter by name. See endpoint description for syntax.","name":"filter[name]","in":"query"},{"schema":{"type":"string","description":"Filter by name_first. See endpoint description for syntax."},"required":false,"description":"Filter by name_first. See endpoint description for syntax.","name":"filter[name_first]","in":"query"},{"schema":{"type":"string","description":"Filter by name_last. See endpoint description for syntax."},"required":false,"description":"Filter by name_last. See endpoint description for syntax.","name":"filter[name_last]","in":"query"},{"schema":{"type":"string","description":"Filter by email. See endpoint description for syntax."},"required":false,"description":"Filter by email. See endpoint description for syntax.","name":"filter[email]","in":"query"},{"schema":{"type":"string","description":"Filter by phone. See endpoint description for syntax."},"required":false,"description":"Filter by phone. See endpoint description for syntax.","name":"filter[phone]","in":"query"}],"responses":{"200":{"description":"Client data retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","description":"The unique identifier of the client"},"name":{"type":"string","nullable":true,"description":"The client's full name"},"email":{"type":"string","nullable":true,"description":"The client's email address"},"phone":{"type":"string","nullable":true,"description":"The client's phone number"},"last_seen_at":{"type":"string","nullable":true,"description":"When the client was last active in the Quilia app (ISO 8601). Engagement signal for spotting disengaged clients; null if they have never been active."},"cases":{"type":"array","items":{"type":"object","properties":{"case_id":{"type":"string","description":"The unique identifier of the case"},"member_id":{"type":"string","description":"The case member ID for this client"},"type":{"type":"string","nullable":true,"description":"The case type"},"status":{"type":"string","nullable":true,"description":"The case status"}},"required":["case_id","member_id","type","status"]},"description":"Array of cases the client is associated with"},"address_1":{"type":"string","description":"First line of the client's address (requires ?fields=address_1)"},"address_2":{"type":"string","description":"Second line of the client's address (requires ?fields=address_2)"},"city":{"type":"string","description":"The client's city (requires ?fields=city)"},"state":{"type":"string","description":"The client's state or province (requires ?fields=state)"},"postal_code":{"type":"string","description":"The client's postal code (requires ?fields=postal_code)"},"country":{"type":"string","description":"The client's country (requires ?fields=country)"},"date_of_birth":{"type":"string","description":"The client's date of birth (requires ?fields=date_of_birth)"},"language":{"type":"string","description":"The client's preferred language (requires ?fields=language)"},"timezone":{"type":"string","description":"The client's timezone (requires ?fields=timezone)"}},"required":["user_id","name","email","phone","last_seen_at","cases"]},"description":"Array of clients"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/clients/{id}":{"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"Delete a client","description":"Permanently deletes a client from the organization's records. This action removes the client's user record, organization membership, and case memberships. Only clients belonging to the authenticated organization can be deleted.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the client to delete"},"required":true,"description":"The unique identifier of the client to delete","name":"id","in":"path"}],"responses":{"200":{"description":"Client successfully deleted from the organization's records","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the delete operation"}},"required":["message"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"Update client information","description":"Updates specific fields of an existing client record. Allows modification of contact details, address information, and demographic data while maintaining data integrity.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the client to update"},"required":true,"description":"The unique identifier of the client to update","name":"id","in":"path"}],"requestBody":{"required":true,"description":"Client update data","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The client's full name"},"email":{"type":"string","nullable":true,"format":"email","description":"The client's email address"},"phone":{"type":"string","nullable":true,"description":"The client's phone number"},"address_1":{"type":"string","nullable":true,"description":"First line of the client's address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the client's address"},"city":{"type":"string","nullable":true,"description":"The client's city"},"state":{"type":"string","nullable":true,"description":"The client's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The client's postal code"},"country":{"type":"string","nullable":true,"description":"The client's country"},"date_of_birth":{"type":"string","nullable":true,"description":"The client's date of birth"},"language":{"type":"string","nullable":true,"description":"The client's preferred language"},"timezone":{"type":"string","nullable":true,"description":"The client's timezone"}}},"example":{"phone":"+15551234567","email":"jane.doe@example.com","address_1":"123 Main St","city":"Springfield","state":"IL","postal_code":"62701","language":"en"}}}},"responses":{"200":{"description":"Client updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"user_id":{"type":"string","description":"The unique identifier of the updated client"}},"required":["user_id"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"Retrieve a single client","description":"Retrieves detailed information for a specific client using either user_id or member_id.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the client to retrieve"},"required":true,"description":"The unique identifier of the client to retrieve","name":"id","in":"path"}],"responses":{"200":{"description":"Client retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"user_id":{"type":"string","nullable":true,"description":"The unique identifier of the client"},"cases":{"type":"array","items":{"type":"object","properties":{"case_id":{"type":"string","description":"The unique identifier of the case"},"member_id":{"type":"string","description":"The case member ID for this client"}},"required":["case_id","member_id"]},"description":"Array of cases the client is associated with"}},"required":["user_id","cases"]}},"required":["message","data"]}}}}}}},"/clients/lookup":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"Lookup client by email or phone","description":"Lookup a client by email or phone number within the authenticated organization. Returns the client record if found.","parameters":[{"schema":{"type":"string","format":"email","description":"Client email address"},"required":false,"description":"Client email address","name":"email","in":"query"},{"schema":{"type":"string","description":"Client phone number"},"required":false,"description":"Client phone number","name":"phone","in":"query"}],"responses":{"200":{"description":"Client found successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"cases":{"type":"array","items":{"type":"object","properties":{"case_id":{"type":"string","description":"The unique identifier of the case"},"member_id":{"type":"string","description":"The case member ID for this client"}},"required":["case_id","member_id"]},"description":"Array of cases the client is associated with"}},"required":["cases"]}},"required":["message","data"]}}}}}}},"/clients/{id}/phase":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["clients"],"summary":"Update client phase","description":"Updates the phase of an individual client. This can be the user_id or the member_id.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The ID of the client to update. This can be the user_id or the member_id."},"required":true,"description":"The ID of the client to update. This can be the user_id or the member_id.","name":"id","in":"path"}],"requestBody":{"required":true,"description":"Client phase update data","content":{"application/json":{"schema":{"type":"object","properties":{"phase":{"type":"string","description":"The new phase for the client"},"case_id":{"type":"string","format":"uuid","description":"The ID of the case to update the client for"}},"required":["phase","case_id"]},"example":{"phase":"Treatment Complete","case_id":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab"}}}},"responses":{"200":{"description":"Client phase updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the phase update operation"},"data":{"type":"object","properties":{"member_id":{"type":"string","description":"The unique identifier of the case member"},"phase":{"type":"string","nullable":true,"description":"The new phase of the client"},"updated_at":{"type":"string","nullable":true,"description":"When the phase was last updated"}},"required":["member_id","phase","updated_at"]}},"required":["message","data"]}}}}}}},"/contacts":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["contacts"],"summary":"Create a new contact","description":"Creates a contact on a case or a client.\n\n**Send the fields flat.** `{ \"type\": \"witness\", \"name\": \"Jane Doe\", \"case_id\": \"…\" }` is the whole body. The older nested form — `{ \"type\": \"people\", \"contact_data\": { … } }` — keeps working forever, and when you send it the outer `type` is only a hint.\n\n**Send your own category label.** We match it case-insensitively against our vocabulary and route it to the right place: a `body shop` is stored as a company and a `witness` as a person whichever bucket you named. A label we cannot place is recorded as `other` rather than failing the call, and your original label is kept alongside it.\n\nOur vocabulary:\n- Companies: body shop, medical provider, rental company, police department, employer, insurance company, law firm, towing company, emergency room, ambulance, vehicle storage\n- People: witness, adjustor, provider, emergency contact, supervisor, ambulance, emergency room, other driver, beneficiary, trustee, executor, guardian, other, creditor, attorney, mediator, guardian ad litem, family, vocational expert, ssa representative, alj, consultative examiner, treating physician\n\n**Required attachment**: every contact needs a `case_id` or a `user_id`. A contact attached to neither belongs to no one and is rejected. `witness`, `adjustor`, `other driver`, `ambulance`, `emergency room`, `police department`, `body shop`, `towing company` and `vehicle storage` are bound to a case specifically, so they need `case_id`.\n\nA police department may carry `police_report_number`.","requestBody":{"required":true,"description":"Contact creation data","content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","description":"The contact category, e.g. `witness` or `body shop`. In the older nested form this is `company` or `people` instead and only hints where an unplaceable label should land."},"name":{"type":"string","description":"The contact's name"},"case_id":{"type":"string","format":"uuid","description":"The case this contact belongs to"},"user_id":{"type":"string","format":"uuid","description":"The client this contact belongs to"},"contact_data":{"type":"object","properties":{},"description":"The nested form, kept for existing integrations. Send the fields flat instead."}}},"examples":{"flat":{"summary":"Witness, flat (preferred)","value":{"type":"witness","name":"Jane Doe","case_id":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","phone":"+15551234567","email":"jane.doe@example.com"}},"unknownLabel":{"summary":"A label we do not know, kept rather than rejected","value":{"type":"Claims Handler","name":"Priya Raman","case_id":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab"}},"witness":{"summary":"Witness, nested (legacy)","value":{"type":"people","contact_data":{"type":"witness","name":"Jane Doe","case_id":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","phone":"+15551234567","email":"jane.doe@example.com"}}},"policeDepartment":{"summary":"Police department (company, case-bound, with report number)","value":{"type":"company","contact_data":{"type":"police department","name":"Springfield Police Department","case_id":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","phone":"+15555550100","police_report_number":"SPD-2026-001234"}}},"medicalProvider":{"summary":"Medical provider (company, can attach to case OR client)","value":{"type":"company","contact_data":{"type":"medical provider","name":"Mercy General Hospital","user_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","phone":"+15555550150","address_1":"123 Main St","city":"Springfield","state":"IL","postal_code":"62701"}}},"emergencyContact":{"summary":"Emergency contact (people, client-bound)","value":{"type":"people","contact_data":{"type":"emergency contact","name":"John Smith","user_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","phone":"+15555550199","relationship":"spouse"}}},"employer":{"summary":"Employer (company, client-bound)","value":{"type":"company","contact_data":{"type":"employer","name":"Acme Corporation","user_id":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","phone":"+15555550175","address_1":"500 Industrial Way","city":"Springfield","state":"IL"}}}}}}},"responses":{"200":{"description":"Contact created successfully","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the creation operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the company contact"},"case_id":{"type":"string","nullable":true,"description":"The case ID this company is associated with"},"user_id":{"type":"string","nullable":true,"description":"The user ID this company is associated with"},"name":{"type":"string","nullable":true,"description":"The company name"},"phone":{"type":"string","nullable":true,"description":"The company phone number"},"address_1":{"type":"string","nullable":true,"description":"First line of the company address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the company address"},"city":{"type":"string","nullable":true,"description":"The company's city"},"state":{"type":"string","nullable":true,"description":"The company's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The company's postal code"},"country":{"type":"string","nullable":true,"description":"The company's country"},"type":{"type":"string","nullable":true,"description":"The type or category of the company"},"police_report_number":{"type":"string","nullable":true,"description":"Police report number (only meaningful for police department contacts)"},"created_at":{"type":"string","description":"ISO timestamp when the company contact was created"}},"required":["id","case_id","user_id","name","phone","address_1","address_2","city","state","postal_code","country","type","police_report_number","created_at"]}},"required":["message","data"]},{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the creation operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the person contact"},"case_id":{"type":"string","nullable":true,"description":"The case ID this person is associated with"},"user_id":{"type":"string","nullable":true,"description":"The user ID this person is associated with"},"email":{"type":"string","nullable":true,"description":"The person's email address"},"phone":{"type":"string","nullable":true,"description":"The person's phone number"},"name":{"type":"string","nullable":true,"description":"The person's full name"},"address_1":{"type":"string","nullable":true,"description":"First line of the person's address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the person's address"},"city":{"type":"string","nullable":true,"description":"The person's city"},"state":{"type":"string","nullable":true,"description":"The person's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The person's postal code"},"country":{"type":"string","nullable":true,"description":"The person's country"},"type":{"type":"string","nullable":true,"description":"The type or category of the person contact"},"relationship":{"type":"string","nullable":true,"enum":["spouse","ex-spouse","parent","child","sibling","grandparent","friend","partner","roommate","relative","other"],"description":"The person's relationship to the case or client"},"created_at":{"type":"string","description":"ISO timestamp when the person contact was created"}},"required":["id","case_id","user_id","email","phone","name","address_1","address_2","city","state","postal_code","country","type","relationship","created_at"]}},"required":["message","data"]}]}}}}}}},"/contacts/{id}":{"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["contacts"],"summary":"Delete a contact","description":"Permanently deletes a contact from the organization's records. This action is irreversible and will remove all contact data. Supports both company and people contacts. Only contacts belonging to the authenticated organization can be deleted.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the contact to delete"},"required":true,"description":"The unique identifier of the contact to delete","name":"id","in":"path"},{"schema":{"type":"string","enum":["company","people"],"description":"The type of contact to delete"},"required":true,"description":"The type of contact to delete","name":"type","in":"query"}],"responses":{"200":{"description":"Contact successfully deleted from the organization's records","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the delete operation"}},"required":["message"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["contacts"],"summary":"Retrieve a contact","description":"Retrieves detailed information for a specific contact (company or person) by ID.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the contact to retrieve"},"required":true,"description":"The unique identifier of the contact to retrieve","name":"id","in":"path"},{"schema":{"type":"string","enum":["company","people"],"description":"The type of contact to retrieve"},"required":true,"description":"The type of contact to retrieve","name":"type","in":"query"}],"responses":{"200":{"description":"Contact retrieved successfully","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the company contact"},"case_id":{"type":"string","nullable":true,"description":"The case ID this company is associated with"},"user_id":{"type":"string","nullable":true,"description":"The user ID this company is associated with"},"name":{"type":"string","nullable":true,"description":"The company name"},"phone":{"type":"string","nullable":true,"description":"The company phone number"},"address_1":{"type":"string","nullable":true,"description":"First line of the company address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the company address"},"city":{"type":"string","nullable":true,"description":"The company's city"},"state":{"type":"string","nullable":true,"description":"The company's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The company's postal code"},"country":{"type":"string","nullable":true,"description":"The company's country"},"type":{"type":"string","nullable":true,"description":"The type or category of the company"},"police_report_number":{"type":"string","nullable":true,"description":"Police report number (only meaningful for police department contacts)"},"created_at":{"type":"string","description":"ISO timestamp when the company contact was created"}},"required":["id","case_id","user_id","name","phone","address_1","address_2","city","state","postal_code","country","type","police_report_number","created_at"]}},"required":["message","data"]},{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the person contact"},"case_id":{"type":"string","nullable":true,"description":"The case ID this person is associated with"},"user_id":{"type":"string","nullable":true,"description":"The user ID this person is associated with"},"email":{"type":"string","nullable":true,"description":"The person's email address"},"phone":{"type":"string","nullable":true,"description":"The person's phone number"},"name":{"type":"string","nullable":true,"description":"The person's full name"},"address_1":{"type":"string","nullable":true,"description":"First line of the person's address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the person's address"},"city":{"type":"string","nullable":true,"description":"The person's city"},"state":{"type":"string","nullable":true,"description":"The person's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The person's postal code"},"country":{"type":"string","nullable":true,"description":"The person's country"},"type":{"type":"string","nullable":true,"description":"The type or category of the person contact"},"relationship":{"type":"string","nullable":true,"enum":["spouse","ex-spouse","parent","child","sibling","grandparent","friend","partner","roommate","relative","other"],"description":"The person's relationship to the case or client"},"created_at":{"type":"string","description":"ISO timestamp when the person contact was created"}},"required":["id","case_id","user_id","email","phone","name","address_1","address_2","city","state","postal_code","country","type","relationship","created_at"]}},"required":["message","data"]}]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["contacts"],"summary":"Update a contact","description":"Updates specific fields of an existing contact. Supports both company and people contacts with comprehensive contact information including name, phone, email, address, and relationship details. Only the provided fields will be updated, maintaining data integrity.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the contact to update"},"required":true,"description":"The unique identifier of the contact to update","name":"id","in":"path"},{"schema":{"type":"string","enum":["company","people"],"description":"The type of contact to update"},"required":true,"description":"The type of contact to update","name":"type","in":"query"}],"requestBody":{"required":true,"description":"Contact update data","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"case_id":{"type":"string","format":"uuid","description":"The case ID this company is associated with"},"user_id":{"type":"string","format":"uuid","description":"The user ID this company is associated with"},"name":{"type":"string","description":"The company name"},"phone":{"type":"string","description":"The company phone number"},"address_1":{"type":"string","description":"First line of the company address"},"address_2":{"type":"string","description":"Second line of the company address"},"city":{"type":"string","description":"The company's city"},"state":{"type":"string","description":"The company's state or province"},"postal_code":{"type":"string","description":"The company's postal code"},"country":{"type":"string","description":"The company's country"},"type":{"type":"string","enum":["body shop","medical provider","rental company","police department","employer","insurance company","law firm","towing company","emergency room","ambulance","vehicle storage"],"description":"The type or category of the company"},"police_report_number":{"type":"string","description":"Police report number (only meaningful for police department contacts)"}}},{"type":"object","properties":{"case_id":{"type":"string","format":"uuid","description":"The case ID this person is associated with"},"user_id":{"type":"string","format":"uuid","description":"The user ID this person is associated with"},"email":{"anyOf":[{"type":"string","format":"email"},{"type":"string","enum":[""]}],"description":"The person's email address"},"phone":{"type":"string","description":"The person's phone number"},"name":{"type":"string","description":"The person's full name"},"address_1":{"type":"string","description":"First line of the person's address"},"address_2":{"type":"string","description":"Second line of the person's address"},"city":{"type":"string","description":"The person's city"},"state":{"type":"string","description":"The person's state or province"},"postal_code":{"type":"string","description":"The person's postal code"},"country":{"type":"string","description":"The person's country"},"type":{"type":"string","enum":["witness","adjustor","provider","emergency contact","supervisor","ambulance","emergency room","other driver","beneficiary","trustee","executor","guardian","other","creditor","attorney","mediator","guardian ad litem","family","vocational expert","ssa representative","alj","consultative examiner","treating physician"],"description":"The type or category of the person contact"},"relationship":{"type":"string","enum":["spouse","ex-spouse","parent","child","sibling","grandparent","friend","partner","roommate","relative","other"],"description":"The person's relationship to the case or client"}}}],"description":"The contact data to update based on the type"},"examples":{"updateCompanyPhone":{"summary":"Update company phone (use with ?type=company)","value":{"phone":"+15555550100","address_1":"500 Industrial Way","city":"Springfield","state":"IL","postal_code":"62701"}},"updatePoliceReportNumber":{"summary":"Update police report number on a police department contact (use with ?type=company)","value":{"police_report_number":"SPD-2026-001234"}},"updatePersonName":{"summary":"Update a person contact (use with ?type=people)","value":{"name":"Jane Doe","phone":"+15555550199","email":"jane.doe@example.com"}}}}}},"responses":{"200":{"description":"Contact updated successfully","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the company contact"},"case_id":{"type":"string","nullable":true,"description":"The case ID this company is associated with"},"user_id":{"type":"string","nullable":true,"description":"The user ID this company is associated with"},"name":{"type":"string","nullable":true,"description":"The company name"},"phone":{"type":"string","nullable":true,"description":"The company phone number"},"address_1":{"type":"string","nullable":true,"description":"First line of the company address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the company address"},"city":{"type":"string","nullable":true,"description":"The company's city"},"state":{"type":"string","nullable":true,"description":"The company's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The company's postal code"},"country":{"type":"string","nullable":true,"description":"The company's country"},"type":{"type":"string","nullable":true,"description":"The type or category of the company"},"police_report_number":{"type":"string","nullable":true,"description":"Police report number (only meaningful for police department contacts)"},"created_at":{"type":"string","description":"ISO timestamp when the company contact was created"},"updated_at":{"type":"string","description":"ISO timestamp when the company contact was last updated"}},"required":["id","case_id","user_id","name","phone","address_1","address_2","city","state","postal_code","country","type","police_report_number","created_at","updated_at"]}},"required":["message","data"]},{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the person contact"},"case_id":{"type":"string","nullable":true,"description":"The case ID this person is associated with"},"user_id":{"type":"string","nullable":true,"description":"The user ID this person is associated with"},"email":{"type":"string","nullable":true,"description":"The person's email address"},"phone":{"type":"string","nullable":true,"description":"The person's phone number"},"name":{"type":"string","nullable":true,"description":"The person's full name"},"address_1":{"type":"string","nullable":true,"description":"First line of the person's address"},"address_2":{"type":"string","nullable":true,"description":"Second line of the person's address"},"city":{"type":"string","nullable":true,"description":"The person's city"},"state":{"type":"string","nullable":true,"description":"The person's state or province"},"postal_code":{"type":"string","nullable":true,"description":"The person's postal code"},"country":{"type":"string","nullable":true,"description":"The person's country"},"type":{"type":"string","nullable":true,"description":"The type or category of the person contact"},"relationship":{"type":"string","nullable":true,"enum":["spouse","ex-spouse","parent","child","sibling","grandparent","friend","partner","roommate","relative","other"],"description":"The person's relationship to the case or client"},"created_at":{"type":"string","description":"ISO timestamp when the person contact was created"},"updated_at":{"type":"string","description":"ISO timestamp when the person contact was last updated"}},"required":["id","case_id","user_id","email","phone","name","address_1","address_2","city","state","postal_code","country","type","relationship","created_at","updated_at"]}},"required":["message","data"]}]}}}}}}},"/documents":{"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["documents"],"summary":"Delete documents","description":"Deletes multiple documents by their document IDs. Automatically handles cleanup of both database records and storage files.","requestBody":{"required":true,"description":"Request body containing the list of document IDs to delete","content":{"application/json":{"schema":{"type":"object","properties":{"documents":{"type":"array","items":{"type":"string"},"description":"Array of document IDs to delete"}},"required":["documents"]},"example":{"documents":["d1e2f3a4-b5c6-4789-9012-3456789abcde","d2e3f4a5-b6c7-4890-9123-4567890bcdef"]}}}},"responses":{"200":{"description":"Documents successfully deleted from storage and database","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the delete operation"}},"required":["message"]}}}}}}},"/documents/{id}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["documents"],"summary":"Retrieve a document","description":"Retrieves a document from the cases bucket and generates a signed URL for secure access. The signed URL expires after 30 minutes for security purposes.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the document to retrieve"},"required":true,"description":"The unique identifier of the document to retrieve","name":"id","in":"path"}],"responses":{"200":{"description":"Document successfully retrieved with a signed URL for access","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"type":{"type":"string","description":"Type of the document"},"signedUrl":{"type":"string","description":"Signed URL of the data. Expires in 30 minutes."}},"required":["message","type","signedUrl"]}}}}}}},"/documents/upload":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["documents"],"summary":"Upload documents","description":"Uploads multiple documents to the cases bucket with automatic file naming and type detection. Supports various file formats and generates unique identifiers for each uploaded document. Also creates tracking records in the assets database table.","requestBody":{"required":true,"description":"Multipart form data containing the files and metadata","content":{"multipart/form-data":{"schema":{"type":"object","properties":{"case_id":{"type":"string","description":"The ID of the case these documents belong to"},"client_id":{"type":"string","description":"The ID of the client these documents belong to"},"type":{"type":"string","enum":["medical record","bill","receipt","repair estimate","police report","damage estimate","accident sketch","explanation video","damage photo","injury photo","mail","insurance form","lab result","prescription","doctor verification","employer verification","pay stub","other"],"default":"other","description":"The type of documents being uploaded"},"description":{"type":"string","description":"Optional description for the uploaded documents"},"file":{"description":"Single file to upload to the specified bucket","format":"binary"},"files":{"type":"array","items":{"format":"binary"},"description":"Array of files to upload to the specified bucket","format":"binary"}},"required":["case_id","client_id"]}}}},"responses":{"200":{"description":"Files successfully uploaded to the bucket","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the upload operation"},"documents":{"type":"array","items":{"type":"string"},"description":"Array of uploaded document IDs"}},"required":["message","documents"]}}}}}}},"/feed":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["feed"],"summary":"Retrieve feed data","description":"Retrieves an organization's activity feed with configurable time ranges. Returns a chronological list of user actions, case updates, and system events. Supports filtering by days, hours, or custom start/end dates. Each feed entry includes metadata about the action, attachments, and relevant context.","parameters":[{"schema":{"type":"number","nullable":true,"description":"Number of days to include in the feed. Takes precedence over hours if both are provided."},"required":false,"description":"Number of days to include in the feed. Takes precedence over hours if both are provided.","name":"days","in":"query"},{"schema":{"type":"number","nullable":true,"description":"Number of hours to include in the feed. Default is 24 hours if neither days nor hours are provided."},"required":false,"description":"Number of hours to include in the feed. Default is 24 hours if neither days nor hours are provided.","name":"hours","in":"query"},{"schema":{"type":"string","description":"Start ISO timestamp","example":"2023-05-20T00:00:00Z"},"required":false,"description":"The start date for the feed data in ISO 8601 format","name":"start","in":"query"},{"schema":{"type":"string","description":"End ISO timestamp","example":"2023-05-25T23:59:59Z"},"required":false,"description":"The end date for the feed data in ISO 8601 format","name":"end","in":"query"}],"responses":{"200":{"description":"Feed data retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"case_id":{"type":"string","nullable":true},"case_member_id":{"type":"string","nullable":true},"logs_data":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"action":{"type":"string"},"log_id":{"type":"string"},"metadata":{"type":"object","properties":{}},"timezone":{"type":"string"},"created_at":{"type":"string"},"attachments":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"fileType":{"type":"string"},"filename":{"type":"string"}},"required":["url","fileType","filename"]}},"description":{"type":"string"}},"required":["title","action","log_id","metadata","timezone","created_at","attachments","description"]}}},"required":["user_id","case_id","case_member_id","logs_data"],"description":"Array of feed entries grouped by user and case"}}},"required":["message","data"]}}}}}}},"/messages":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["messages"],"summary":"Create a new message","description":"Creates a new message in the system. Messages are used to communicate between the organization and clients. The message will be associated with the authenticated organization and can include both a subject and HTML body content.","requestBody":{"required":true,"description":"Message creation data including sender, recipient, subject, and body","content":{"application/json":{"schema":{"type":"object","properties":{"sender":{"type":"string","description":"The user ID of the sender. Must be a valid user within the organization. This tracks who actually sent the message."},"sender_org":{"type":"boolean","description":"If true, the message will be displayed as sent from the organization rather than the individual user. The sender field still tracks who actually sent it."},"recipient":{"type":"string","minLength":1,"description":"The user ID of the recipient. This will be stored as recipient_user in the database. Either recipient or caseId must be provided. When caseId is given without a recipient, the message is delivered to every client on the case."},"caseId":{"type":"string","minLength":1,"description":"The case ID to associate the message with. This will be stored as recipient_case in the database. Either recipient or caseId must be provided. On its own it addresses every client on the case; combined with recipient it scopes that one message to the case."},"message_subject":{"type":"string","description":"The subject line of the message"},"message_body":{"type":"string","description":"The body content of the message. Supports HTML formatting"},"scheduled_date":{"type":"string","description":"ISO 8601 timestamp for when the message should be sent. Must be a future date. If provided, the message will be scheduled; otherwise, it will be sent immediately."},"channels":{"type":"object","properties":{"sms":{"type":"string","enum":["always","fallback","never"]},"email":{"type":"boolean"}},"description":"Optional delivery preferences. Push is always enabled. Omitted values default to SMS always and email enabled."}},"required":["sender","message_subject","message_body"]},"examples":{"toCase":{"summary":"Message to a case (everyone on the case)","value":{"sender":"e1f2a3b4-c5d6-4789-9012-3456789abcde","caseId":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","message_subject":"Update on your case","message_body":"<p>Hi, we received your medical records and have started reviewing them.</p>"}},"toClientFromOrg":{"summary":"Message to one client, signed as the firm","value":{"sender":"e1f2a3b4-c5d6-4789-9012-3456789abcde","sender_org":true,"recipient":"7b9e4c10-2a3a-4b8c-9e0d-abcdef012345","message_subject":"Welcome to Acme Law","message_body":"<p>Welcome aboard. Your case manager will reach out within one business day.</p>"}},"scheduled":{"summary":"Schedule a message for later","value":{"sender":"e1f2a3b4-c5d6-4789-9012-3456789abcde","caseId":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","message_subject":"Reminder: appointment tomorrow","message_body":"<p>Reminder: your follow-up appointment is tomorrow at 3pm.</p>","scheduled_date":"2026-06-09T18:00:00.000Z"}}}}}},"responses":{"200":{"description":"Message created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"messageId":{"type":"string","description":"The unique identifier of the created message. When a caseId addresses several clients, this is the first of messageIds."},"messageIds":{"type":"array","items":{"type":"string"},"description":"Every message created by the request — one per recipient. A caseId with no explicit recipient creates one message per client on the case."},"message":{"type":"string","description":"Success message confirming the message creation"}},"required":["messageId","messageIds","message"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["messages"],"summary":"List messages","description":"Retrieves a paginated list of messages for the authenticated organization. Returns message metadata including sender, recipient, subject, body, status, and timestamps, with configurable limit and offset for pagination.","parameters":[{"schema":{"type":"number","nullable":true,"default":10,"description":"The maximum number of messages to return."},"required":false,"description":"The maximum number of messages to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"The number of messages to skip before starting to return results."},"required":false,"description":"The number of messages to skip before starting to return results.","name":"offset","in":"query"}],"responses":{"200":{"description":"List of messages retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the message"},"sender":{"type":"string","nullable":true,"description":"The user ID of the message sender"},"recipient":{"type":"string","nullable":true,"description":"The user ID of the message recipient"},"caseId":{"type":"string","nullable":true,"description":"The case ID associated with the message"},"message_subject":{"type":"string","nullable":true,"description":"The subject line of the message"},"message_body":{"type":"string","nullable":true,"description":"The body content of the message"},"status":{"type":"string","nullable":true,"description":"The current delivery/processing status of the message"},"is_unread":{"type":"boolean","description":"Whether the message has been read by the recipient"},"created_at":{"type":"string","description":"ISO timestamp when the message was created"},"updated_at":{"type":"string","description":"ISO timestamp when the message was last updated"}},"required":["id","sender","recipient","caseId","message_subject","message_body","status","is_unread","created_at","updated_at"]},"description":"Array of messages"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/messages/{id}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["messages"],"summary":"Retrieve a message","description":"Retrieves detailed information about a specific message by its ID. Returns comprehensive message metadata including sender, recipient, content, status, and timestamps. Only messages belonging to the authenticated organization can be retrieved.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the message to retrieve"},"required":true,"description":"The unique identifier of the message to retrieve","name":"id","in":"path"}],"responses":{"200":{"description":"Message retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the message"},"sender":{"type":"string","nullable":true,"description":"The user ID of the message sender"},"recipient":{"type":"string","nullable":true,"description":"The user ID of the message recipient"},"caseId":{"type":"string","nullable":true,"description":"The case ID associated with the message"},"message_subject":{"type":"string","nullable":true,"description":"The subject line of the message"},"message_body":{"type":"string","nullable":true,"description":"The body content of the message, may include HTML formatting"},"status":{"type":"string","nullable":true,"description":"The current delivery/processing status of the message"},"is_unread":{"type":"boolean","description":"Whether the message has been read by the recipient"},"created_at":{"type":"string","description":"ISO timestamp when the message was created"},"updated_at":{"type":"string","description":"ISO timestamp when the message was last updated"}},"required":["id","sender","recipient","caseId","message_subject","message_body","status","is_unread","created_at","updated_at"],"description":"Message data with core fields and metadata"}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["messages"],"summary":"Update a scheduled message","description":"Corrects the subject or body of a message that has not gone out yet. The scheduled sender reads the row when it fires, so an edit made before then is what the client receives. Only messages the organization owns, and only while they are still `scheduled` or `draft` — a message that has already been sent is in the client's inbox and cannot be rewritten. Messages generated by an automation are refused: the automation regenerates them from its own template, so the edit would be silently reverted. Edit the automation instead.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the message to update"},"required":true,"description":"The unique identifier of the message to update","name":"id","in":"path"}],"requestBody":{"required":true,"description":"The fields to change. Send only the ones you are changing.","content":{"application/json":{"schema":{"type":"object","properties":{"message_subject":{"type":"string","minLength":1,"description":"Replacement subject line"},"message_body":{"type":"string","minLength":1,"description":"Replacement body. Supports HTML, the same as on create. This replaces the body outright rather than patching part of it."}}},"examples":{"fixTheBody":{"summary":"Correct the body of a scheduled message","value":{"message_body":"<p>Hi, one correction: your appointment moved to Thursday at 3pm.</p>"}},"fixBoth":{"summary":"Correct the subject and body together","value":{"message_subject":"Your appointment moved to Thursday","message_body":"<p>Hi, one correction: your appointment moved to Thursday at 3pm.</p>"}}}}}},"responses":{"200":{"description":"Message updated","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the message"},"message_subject":{"type":"string","nullable":true,"description":"The subject line as it now stands"},"message_body":{"type":"string","nullable":true,"description":"The body as it now stands, may include HTML formatting"},"status":{"type":"string","nullable":true,"description":"The message's status, unchanged by this route — an edit never sends or unsends"},"scheduled_date":{"type":"string","nullable":true,"description":"ISO timestamp of when the message is due to go out. The sender polls every 15 minutes, so this is the deadline an edit has to beat."},"updated_at":{"type":"string","description":"ISO timestamp when the message was last updated"}},"required":["id","message_subject","message_body","status","scheduled_date","updated_at"],"description":"The message as it stands after the update"}},"required":["message","data"]}}}}}}},"/org":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Retrieve the caller's organization profile","description":"Returns the authenticated caller's own firm profile and contact settings (name, address, phone, website, social links, hours, referral email). The organization is resolved from the credential, so there is no id in the path.","responses":{"200":{"description":"Organization profile retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The organization id"},"name":{"type":"string","nullable":true,"description":"The firm name"},"phone":{"type":"string","nullable":true,"description":"Primary phone number"},"email":{"type":"string","nullable":true,"description":"Primary contact email"},"address_1":{"type":"string","nullable":true,"description":"Street address line 1"},"address_2":{"type":"string","nullable":true,"description":"Street address line 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"country":{"type":"string","nullable":true,"description":"Country"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"website":{"type":"string","nullable":true,"description":"Firm website URL"},"timezone":{"type":"string","nullable":true,"description":"Firm time zone (IANA name)"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL or handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL or handle"},"twitter":{"type":"string","nullable":true,"description":"X / Twitter URL or handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL or handle"},"operation_hours_weekdays":{"type":"string","nullable":true,"description":"Weekday hours, e.g. \"09:00-17:00\""},"operation_hours_weekends":{"type":"string","nullable":true,"description":"Weekend hours, e.g. \"10:00-14:00\" (or null if closed)"},"referrals_email":{"type":"string","nullable":true,"description":"Email address that receives referral notifications"},"button_icon_color":{"type":"string","nullable":true,"description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_icon_color instead. Brand \"inside icon\" color (hex)"},"secondary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_background_color instead. Brand \"outside icon\" color (hex)"},"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL (read-only — set with POST /org/branding)"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL (read-only — set with POST /org/branding)"},"invite_message_templates":{"type":"object","nullable":true,"properties":{"en":{"type":"string","minLength":1},"es":{"type":"string","minLength":1},"ht":{"type":"string","minLength":1},"km":{"type":"string","minLength":1},"ko":{"type":"string","minLength":1},"th":{"type":"string","minLength":1},"tl":{"type":"string","minLength":1},"zh_cn":{"type":"string","minLength":1},"zh_tw":{"type":"string","minLength":1},"vi":{"type":"string","minLength":1},"pt":{"type":"string","minLength":1}},"description":"Per-language custom client invite SMS templates, keyed by language code. Replaces the whole map when set; pass null to revert every language to the default message."},"organization_alert":{"type":"object","nullable":true,"properties":{"enabled":{"type":"boolean","description":"Whether the alert is shown to clients"},"message":{"type":"string","minLength":1,"description":"The alert text shown in the app"},"starts_at":{"type":"string","nullable":true,"format":"date-time","description":"UTC ISO timestamp when the alert starts showing; omit or null to show immediately"},"expires_at":{"type":"string","nullable":true,"format":"date-time","description":"UTC ISO timestamp when the alert stops showing; omit or null for no end date"}},"required":["enabled","message"],"description":"A banner alert shown to all of the firm's clients in the app (e.g. holiday closure). Pass null to clear the alert."},"faqs_enabled":{"type":"boolean","nullable":true,"description":"Whether client-facing FAQs are enabled"},"client_features":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Client-facing feature flags (read-only)"},"client_language_distribution":{"type":"object","nullable":true,"additionalProperties":{"type":"number"},"description":"Client language distribution (base language code -> count). \"unset\" tracks clients with no language."}},"required":["id","name","phone","email","address_1","address_2","city","state","country","postal_code","website","timezone","review_link","payments_url","facebook","instagram","twitter","linkedin","tiktok","operation_hours_weekdays","operation_hours_weekends","referrals_email","button_icon_color","button_background_color","primary_color","secondary_color","logo_image","icon_image","invite_message_templates","organization_alert","faqs_enabled"],"description":"The firm's editable profile and contact settings"}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Update the caller's organization profile","description":"Updates the authenticated caller's own firm profile and contact settings. Only the fields provided are changed; omitted fields are left untouched. Requires an admin role at the firm. The organization is resolved from the credential, so there is no id in the path.","requestBody":{"required":true,"description":"Organization fields to update","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"description":"The firm name"},"phone":{"type":"string","nullable":true,"description":"Primary phone number"},"email":{"type":"string","nullable":true,"description":"Primary contact email"},"address_1":{"type":"string","nullable":true,"description":"Street address 1"},"address_2":{"type":"string","nullable":true,"description":"Street address 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"country":{"type":"string","nullable":true,"description":"Country"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"website":{"type":"string","nullable":true,"description":"Firm website URL"},"timezone":{"type":"string","nullable":true,"description":"Firm time zone (IANA name, e.g. \"America/Chicago\")"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL/handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL/handle"},"twitter":{"type":"string","nullable":true,"description":"X/Twitter URL/handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL/handle"},"operation_hours_weekdays":{"type":"string","nullable":true,"pattern":"^([01]?\\d|2[0-3]):[0-5]\\d-([01]?\\d|2[0-3]):[0-5]\\d$","description":"Weekday hours, e.g. \"09:00-17:00\""},"operation_hours_weekends":{"type":"string","nullable":true,"pattern":"^([01]?\\d|2[0-3]):[0-5]\\d-([01]?\\d|2[0-3]):[0-5]\\d$","description":"Weekend hours, e.g. \"10:00-14:00\""},"referrals_email":{"type":"string","nullable":true,"description":"Email that receives referral notifications"},"button_icon_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Deprecated: use button_icon_color instead."},"secondary_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Deprecated: use button_background_color instead."},"invite_message_templates":{"type":"object","nullable":true,"properties":{"en":{"type":"string","minLength":1},"es":{"type":"string","minLength":1},"ht":{"type":"string","minLength":1},"km":{"type":"string","minLength":1},"ko":{"type":"string","minLength":1},"th":{"type":"string","minLength":1},"tl":{"type":"string","minLength":1},"zh_cn":{"type":"string","minLength":1},"zh_tw":{"type":"string","minLength":1},"vi":{"type":"string","minLength":1},"pt":{"type":"string","minLength":1}},"description":"Per-language custom client invite SMS templates, keyed by language code. Replaces the whole map when set; pass null to revert every language to the default message."},"organization_alert":{"type":"object","nullable":true,"properties":{"enabled":{"type":"boolean","description":"Whether the alert is shown to clients"},"message":{"type":"string","minLength":1,"description":"The alert text shown in the app"},"starts_at":{"type":"string","nullable":true,"format":"date-time","description":"UTC ISO timestamp when the alert starts showing; omit or null to show immediately"},"expires_at":{"type":"string","nullable":true,"format":"date-time","description":"UTC ISO timestamp when the alert stops showing; omit or null for no end date"}},"required":["enabled","message"],"description":"A banner alert shown to all of the firm's clients in the app (e.g. holiday closure). Pass null to clear the alert."},"faqs_enabled":{"type":"boolean","nullable":true,"description":"Whether client-facing FAQs are enabled"}},"description":"Fields to update on the organization. Omitted fields are unchanged."},"examples":{"address":{"summary":"Update the firm address and phone","value":{"address_1":"123 Main St","city":"Austin","state":"TX","postal_code":"78701","phone":"+15555550140"}},"hours":{"summary":"Update operating hours","value":{"operation_hours_weekdays":"09:00-17:00","operation_hours_weekends":null}},"branding":{"summary":"Set the brand colors","value":{"button_icon_color":"#1D4ED8","button_background_color":"#F8FAFC"}},"alert":{"summary":"Post a client-facing alert, then clear it","value":{"organization_alert":{"enabled":true,"message":"Our office is closed Monday for the holiday.","starts_at":"2026-08-03T12:00:00.000Z","expires_at":"2026-08-04T12:00:00.000Z"}}}}}}},"responses":{"200":{"description":"Organization updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The organization id"},"name":{"type":"string","nullable":true,"description":"The firm name"},"phone":{"type":"string","nullable":true,"description":"Primary phone number"},"email":{"type":"string","nullable":true,"description":"Primary contact email"},"address_1":{"type":"string","nullable":true,"description":"Street address line 1"},"address_2":{"type":"string","nullable":true,"description":"Street address line 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"country":{"type":"string","nullable":true,"description":"Country"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"website":{"type":"string","nullable":true,"description":"Firm website URL"},"timezone":{"type":"string","nullable":true,"description":"Firm time zone (IANA name)"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL or handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL or handle"},"twitter":{"type":"string","nullable":true,"description":"X / Twitter URL or handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL or handle"},"operation_hours_weekdays":{"type":"string","nullable":true,"description":"Weekday hours, e.g. \"09:00-17:00\""},"operation_hours_weekends":{"type":"string","nullable":true,"description":"Weekend hours, e.g. \"10:00-14:00\" (or null if closed)"},"referrals_email":{"type":"string","nullable":true,"description":"Email address that receives referral notifications"},"button_icon_color":{"type":"string","nullable":true,"description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_icon_color instead. Brand \"inside icon\" color (hex)"},"secondary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_background_color instead. Brand \"outside icon\" color (hex)"},"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL (read-only — set with POST /org/branding)"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL (read-only — set with POST /org/branding)"},"invite_message_templates":{"type":"object","nullable":true,"properties":{"en":{"type":"string","minLength":1},"es":{"type":"string","minLength":1},"ht":{"type":"string","minLength":1},"km":{"type":"string","minLength":1},"ko":{"type":"string","minLength":1},"th":{"type":"string","minLength":1},"tl":{"type":"string","minLength":1},"zh_cn":{"type":"string","minLength":1},"zh_tw":{"type":"string","minLength":1},"vi":{"type":"string","minLength":1},"pt":{"type":"string","minLength":1}},"description":"Per-language custom client invite SMS templates, keyed by language code. Replaces the whole map when set; pass null to revert every language to the default message."},"organization_alert":{"type":"object","nullable":true,"properties":{"enabled":{"type":"boolean","description":"Whether the alert is shown to clients"},"message":{"type":"string","minLength":1,"description":"The alert text shown in the app"},"starts_at":{"type":"string","nullable":true,"format":"date-time","description":"UTC ISO timestamp when the alert starts showing; omit or null to show immediately"},"expires_at":{"type":"string","nullable":true,"format":"date-time","description":"UTC ISO timestamp when the alert stops showing; omit or null for no end date"}},"required":["enabled","message"],"description":"A banner alert shown to all of the firm's clients in the app (e.g. holiday closure). Pass null to clear the alert."},"faqs_enabled":{"type":"boolean","nullable":true,"description":"Whether client-facing FAQs are enabled"},"client_features":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Client-facing feature flags (read-only)"},"client_language_distribution":{"type":"object","nullable":true,"additionalProperties":{"type":"number"},"description":"Client language distribution (base language code -> count). \"unset\" tracks clients with no language."}},"required":["id","name","phone","email","address_1","address_2","city","state","country","postal_code","website","timezone","review_link","payments_url","facebook","instagram","twitter","linkedin","tiktok","operation_hours_weekdays","operation_hours_weekends","referrals_email","button_icon_color","button_background_color","primary_color","secondary_color","logo_image","icon_image","invite_message_templates","organization_alert","faqs_enabled"],"description":"The firm's editable profile and contact settings"}},"required":["message","data"]}}}}}}},"/org/locations":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"List the firm's locations","description":"Returns all of the caller's firm office locations.","responses":{"200":{"description":"Locations retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"The location id"},"is_primary":{"type":"boolean","description":"True if this is the primary location"},"name":{"type":"string","nullable":true,"description":"Location name (e.g. \"Downtown Office\")"},"is_virtual":{"type":"boolean","description":"Virtual location (no physical address) — clears address fields"},"address_1":{"type":"string","nullable":true,"description":"Street address line 1"},"address_2":{"type":"string","nullable":true,"description":"Street address line 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"country":{"type":"string","nullable":true,"description":"Country"},"phone":{"type":"string","nullable":true,"description":"Location phone number"},"email":{"type":"string","nullable":true,"description":"Location email"},"timezone":{"type":"string","nullable":true,"description":"Location time zone (IANA name)"},"website":{"type":"string","nullable":true,"description":"Location website URL"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"referrals_email":{"type":"string","nullable":true,"description":"Referral notifications email"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL/handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL/handle"},"twitter":{"type":"string","nullable":true,"description":"X/Twitter URL/handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL/handle"},"branding":{"type":"object","properties":{"state":{"type":"string","enum":["set","cleared","unconfigured"],"description":"The configuration state of this location's branding"},"details":{"type":"object","nullable":true,"properties":{"enabled":{"type":"boolean","description":"Whether this location overrides the firm-level branding"},"name":{"type":"string","nullable":true,"description":"Client-facing name for this location"},"button_icon_color":{"type":"string","nullable":true,"description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_icon_color instead."},"secondary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_background_color instead."},"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL"}},"required":["enabled","name","button_icon_color","button_background_color","primary_color","secondary_color","logo_image","icon_image"],"description":"The saved branding details, if any have been configured"}},"required":["state","details"],"description":"The per-location branding configuration"}},"required":["id","is_primary","name","is_virtual","address_1","address_2","city","state","postal_code","country","phone","email","timezone","website","review_link","payments_url","referrals_email","facebook","instagram","twitter","linkedin","tiktok","branding"]}}},"required":["message","data"]}}}}}},"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Add a firm location","description":"Adds a new office location to the firm. Requires an admin role. Set is_virtual=true for a location with no physical address (address fields are cleared).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","nullable":true,"description":"Location name"},"is_virtual":{"type":"boolean","description":"Virtual location — when true the address fields are cleared"},"address_1":{"type":"string","nullable":true,"description":"Street address 1"},"address_2":{"type":"string","nullable":true,"description":"Street address 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"country":{"type":"string","nullable":true,"description":"Country"},"phone":{"type":"string","nullable":true,"description":"Location phone"},"email":{"type":"string","nullable":true,"format":"email","description":"Location email"},"timezone":{"type":"string","nullable":true,"description":"Time zone (IANA name)"},"website":{"type":"string","nullable":true,"description":"Location website"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"referrals_email":{"type":"string","nullable":true,"format":"email","description":"Referral notifications email"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL/handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL/handle"},"twitter":{"type":"string","nullable":true,"description":"X/Twitter URL/handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL/handle"}},"description":"A new firm location. Address optional for virtual locations."}}}},"responses":{"200":{"description":"Location created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"The location id"},"is_primary":{"type":"boolean","description":"True if this is the primary location"},"name":{"type":"string","nullable":true,"description":"Location name (e.g. \"Downtown Office\")"},"is_virtual":{"type":"boolean","description":"Virtual location (no physical address) — clears address fields"},"address_1":{"type":"string","nullable":true,"description":"Street address line 1"},"address_2":{"type":"string","nullable":true,"description":"Street address line 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"country":{"type":"string","nullable":true,"description":"Country"},"phone":{"type":"string","nullable":true,"description":"Location phone number"},"email":{"type":"string","nullable":true,"description":"Location email"},"timezone":{"type":"string","nullable":true,"description":"Location time zone (IANA name)"},"website":{"type":"string","nullable":true,"description":"Location website URL"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"referrals_email":{"type":"string","nullable":true,"description":"Referral notifications email"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL/handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL/handle"},"twitter":{"type":"string","nullable":true,"description":"X/Twitter URL/handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL/handle"},"branding":{"type":"object","properties":{"state":{"type":"string","enum":["set","cleared","unconfigured"],"description":"The configuration state of this location's branding"},"details":{"type":"object","nullable":true,"properties":{"enabled":{"type":"boolean","description":"Whether this location overrides the firm-level branding"},"name":{"type":"string","nullable":true,"description":"Client-facing name for this location"},"button_icon_color":{"type":"string","nullable":true,"description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_icon_color instead."},"secondary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_background_color instead."},"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL"}},"required":["enabled","name","button_icon_color","button_background_color","primary_color","secondary_color","logo_image","icon_image"],"description":"The saved branding details, if any have been configured"}},"required":["state","details"],"description":"The per-location branding configuration"}},"required":["id","is_primary","name","is_virtual","address_1","address_2","city","state","postal_code","country","phone","email","timezone","website","review_link","payments_url","referrals_email","facebook","instagram","twitter","linkedin","tiktok","branding"]}},"required":["message","data"]}}}}}}},"/org/locations/{id}":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Update a firm location","description":"Updates a firm location. Only the fields provided are changed. Requires an admin role.","parameters":[{"schema":{"type":"number","nullable":true,"description":"The location id"},"required":false,"description":"The location id","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","nullable":true,"description":"Location name"},"is_virtual":{"type":"boolean","description":"Virtual location — when true the address fields are cleared"},"address_1":{"type":"string","nullable":true,"description":"Street address 1"},"address_2":{"type":"string","nullable":true,"description":"Street address 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"country":{"type":"string","nullable":true,"description":"Country"},"phone":{"type":"string","nullable":true,"description":"Location phone"},"email":{"type":"string","nullable":true,"format":"email","description":"Location email"},"timezone":{"type":"string","nullable":true,"description":"Time zone (IANA name)"},"website":{"type":"string","nullable":true,"description":"Location website"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"referrals_email":{"type":"string","nullable":true,"format":"email","description":"Referral notifications email"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL/handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL/handle"},"twitter":{"type":"string","nullable":true,"description":"X/Twitter URL/handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL/handle"}},"description":"Location fields to update. Omitted fields are unchanged."}}}},"responses":{"200":{"description":"Location updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"number","description":"The location id"},"is_primary":{"type":"boolean","description":"True if this is the primary location"},"name":{"type":"string","nullable":true,"description":"Location name (e.g. \"Downtown Office\")"},"is_virtual":{"type":"boolean","description":"Virtual location (no physical address) — clears address fields"},"address_1":{"type":"string","nullable":true,"description":"Street address line 1"},"address_2":{"type":"string","nullable":true,"description":"Street address line 2"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State or region"},"postal_code":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"country":{"type":"string","nullable":true,"description":"Country"},"phone":{"type":"string","nullable":true,"description":"Location phone number"},"email":{"type":"string","nullable":true,"description":"Location email"},"timezone":{"type":"string","nullable":true,"description":"Location time zone (IANA name)"},"website":{"type":"string","nullable":true,"description":"Location website URL"},"review_link":{"type":"string","nullable":true,"description":"Public review link"},"payments_url":{"type":"string","nullable":true,"description":"Online payments URL"},"referrals_email":{"type":"string","nullable":true,"description":"Referral notifications email"},"facebook":{"type":"string","nullable":true,"description":"Facebook URL/handle"},"instagram":{"type":"string","nullable":true,"description":"Instagram URL/handle"},"twitter":{"type":"string","nullable":true,"description":"X/Twitter URL/handle"},"linkedin":{"type":"string","nullable":true,"description":"LinkedIn URL"},"tiktok":{"type":"string","nullable":true,"description":"TikTok URL/handle"},"branding":{"type":"object","properties":{"state":{"type":"string","enum":["set","cleared","unconfigured"],"description":"The configuration state of this location's branding"},"details":{"type":"object","nullable":true,"properties":{"enabled":{"type":"boolean","description":"Whether this location overrides the firm-level branding"},"name":{"type":"string","nullable":true,"description":"Client-facing name for this location"},"button_icon_color":{"type":"string","nullable":true,"description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_icon_color instead."},"secondary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_background_color instead."},"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL"}},"required":["enabled","name","button_icon_color","button_background_color","primary_color","secondary_color","logo_image","icon_image"],"description":"The saved branding details, if any have been configured"}},"required":["state","details"],"description":"The per-location branding configuration"}},"required":["id","is_primary","name","is_virtual","address_1","address_2","city","state","postal_code","country","phone","email","timezone","website","review_link","payments_url","referrals_email","facebook","instagram","twitter","linkedin","tiktok","branding"]}},"required":["message","data"]}}}}}},"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Delete a firm location","description":"Removes a firm location. Requires an admin role.","parameters":[{"schema":{"type":"number","nullable":true,"description":"The location id"},"required":false,"description":"The location id","name":"id","in":"path"}],"responses":{"200":{"description":"Location deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]}}}}}}},"/org/locations/{id}/branding":{"put":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Set a location's branding","description":"Sets a single location's branding override — its own name, colors, logo and icon shown to that location's clients instead of the firm-level branding. Set enabled=false to fall back to firm branding without discarding the values. Images are given as publicly reachable https URLs (10MB max) and re-hosted by Quilia, which resizes anything over 1600px. Omitted fields keep their current value; null clears one. Requires an admin role.","parameters":[{"schema":{"type":"number","nullable":true,"description":"The location id"},"required":false,"description":"The location id","name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Turn this location's own branding on or off. When off, clients see the firm-level branding."},"name":{"type":"string","nullable":true,"description":"Client-facing name for this location"},"button_icon_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Deprecated: use button_icon_color instead."},"secondary_color":{"type":"string","nullable":true,"pattern":"^#[0-9A-Fa-f]{6}$","description":"Deprecated: use button_background_color instead."},"logo_url":{"type":"string","nullable":true,"format":"uri","description":"The firm's full logo. ~2.6:1 aspect ratio, 1200x460 px, scaled to 64pt tall. Dark or full-color on transparent background (no reverse/knockout variants, no baked-in background). Acts as a fallback in circular slots when icon is missing. Publicly reachable https image URL (PNG, JPG, GIF or WebP, 10MB max) — we download it, resize anything over 1600px, and host our own copy. Pass null to remove the current image."},"icon_url":{"type":"string","nullable":true,"format":"uri","description":"The firm's icon. Square canvas (1:1), 512x512 px minimum, rendered as a circle in the app (keep mark inside inscribed circle with margin, corners are cropped). Legible at 32pt (monogram/brandmark, not a wordmark). Dark or full-color on transparent background (no reverse/knockout variants, no baked-in background). Publicly reachable https image URL (PNG, JPG, GIF or WebP, 10MB max) — we download it, resize anything over 1600px, and host our own copy. Pass null to remove the current image."}},"required":["enabled"],"description":"Sets a location's branding override. Omitted fields keep their current value."}}}},"responses":{"200":{"description":"Location branding updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Whether this location overrides the firm-level branding"},"name":{"type":"string","nullable":true,"description":"Client-facing name for this location"},"button_icon_color":{"type":"string","nullable":true,"description":"Foreground icon color on the firm's profile action buttons (hex)"},"button_background_color":{"type":"string","nullable":true,"description":"Background tile color on the firm's profile action buttons (hex)"},"primary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_icon_color instead."},"secondary_color":{"type":"string","nullable":true,"description":"Deprecated: use button_background_color instead."},"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL"}},"required":["enabled","name","button_icon_color","button_background_color","primary_color","secondary_color","logo_image","icon_image"]}},"required":["message","data"]}}}}}}},"/org/branding":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Set the firm's logo and icon","description":"Sets the firm's logo and/or icon from publicly reachable image URLs (for example the logo already published on the firm's website). The image is downloaded and re-hosted by Quilia, so the source URL does not need to stay available. PNG, JPG, GIF or WebP, 10MB max, resized to 1600px if larger; the icon is displayed as a square, so a square source works best. Pass null for a field to remove that image. Requires an admin role.","requestBody":{"required":true,"description":"Image URLs to set (at least one)","content":{"application/json":{"schema":{"type":"object","properties":{"logo_url":{"type":"string","nullable":true,"format":"uri","description":"The firm's full logo. ~2.6:1 aspect ratio, 1200x460 px, scaled to 64pt tall. Dark or full-color on transparent background (no reverse/knockout variants, no baked-in background). Acts as a fallback in circular slots when icon is missing. Publicly reachable https image URL (PNG, JPG, GIF or WebP, 10MB max) — we download it, resize anything over 1600px, and host our own copy. Pass null to remove the current image."},"icon_url":{"type":"string","nullable":true,"format":"uri","description":"The firm's icon. Square canvas (1:1), 512x512 px minimum, rendered as a circle in the app (keep mark inside inscribed circle with margin, corners are cropped). Legible at 32pt (monogram/brandmark, not a wordmark). Dark or full-color on transparent background (no reverse/knockout variants, no baked-in background). Publicly reachable https image URL (PNG, JPG, GIF or WebP, 10MB max) — we download it, resize anything over 1600px, and host our own copy. Pass null to remove the current image."}},"description":"Sets the firm's logo and icon from image URLs. Provide at least one field; omitted fields are left unchanged."},"examples":{"logo":{"summary":"Set the firm logo from its website","value":{"logo_url":"https://example.com/img/firm-logo.png"}},"clear":{"summary":"Remove the icon","value":{"icon_url":null}}}}}},"responses":{"200":{"description":"Branding updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"logo_image":{"type":"string","nullable":true,"description":"Hosted logo URL"},"icon_image":{"type":"string","nullable":true,"description":"Hosted icon URL"}},"required":["logo_image","icon_image"]}},"required":["message","data"]}}}}}}},"/org/faqs":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"List the firm's FAQs","description":"Returns the firm's client-facing FAQs (shown in the Quilia app), in display order.","parameters":[{"schema":{"type":"string","description":"Optional language code (e.g. es). If provided, returns FAQs translated to this language, falling back to English."},"required":false,"description":"Optional language code (e.g. es). If provided, returns FAQs translated to this language, falling back to English.","name":"language","in":"query"}],"responses":{"200":{"description":"FAQs retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable FAQ id (server-generated)"},"order":{"type":"number","description":"Display order (0-based)"},"question":{"type":"string","description":"The question"},"answer":{"type":"string","description":"The answer"}},"required":["id","order","question","answer"]}}},"required":["message","data"]}}}}}},"put":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Replace the firm's FAQs","description":"Replaces the firm's FAQ list with the provided questions/answers (in order). ids and ordering are assigned server-side, and English translations are rebuilt. Requires an admin role.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"faqs":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"description":"The question"},"answer":{"type":"string","minLength":1,"description":"The answer"}},"required":["question","answer"]},"description":"The complete FAQ list, in display order. Replaces existing."},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"The language code"},"faqs":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string","minLength":1,"description":"The translated question"},"answer":{"type":"string","minLength":1,"description":"The translated answer"}},"required":["question","answer"]},"description":"Translated FAQs matching the order of the base faqs array"}},"required":["language","faqs"]},"description":"Translations for the FAQs"}},"required":["faqs"],"description":"Replace the firm FAQ list"}}}},"responses":{"200":{"description":"FAQs updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable FAQ id (server-generated)"},"order":{"type":"number","description":"Display order (0-based)"},"question":{"type":"string","description":"The question"},"answer":{"type":"string","description":"The answer"}},"required":["id","order","question","answer"]}}},"required":["message","data"]}}}}}}},"/org/setup-status":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Firm setup-status checklist","description":"Returns a config-completeness checklist for the caller's firm (profile, team, locations, case types, client features, FAQs, intake forms, task lists, CMS connection). Use it to see what's set up and what's still needed when guiding onboarding. Case types count as unconfigured until the firm turns some off — they are all on by default, so an untouched firm is showing its clients every symptom list Quilia has.","responses":{"200":{"description":"Setup status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Stable identifier for the setup area"},"label":{"type":"string","description":"Human-readable area name"},"complete":{"type":"boolean","description":"Whether this area is configured"},"summary":{"type":"string","description":"One-line status of this area"},"hint":{"type":"string","nullable":true,"description":"What to do next when incomplete (null when complete)"},"client_features":{"type":"object","additionalProperties":{"type":"boolean"},"description":"Structured feature map (only present on the features item)"}},"required":["key","label","complete","summary","hint"]}}},"required":["message","data"]}}}}}}},"/org/integrations":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"List the firm's integration settings","description":"Returns every integration configured for the caller's firm, including its operational toggles, feed settings, service-specific config and connection health. Credentials, sessions, tokens and encrypted values are deliberately excluded.","parameters":[{"schema":{"type":"string","description":"Return only this integration service, e.g. filevine or clio"},"required":false,"description":"Return only this integration service, e.g. filevine or clio","name":"cms_type","in":"query"}],"responses":{"200":{"description":"Integration settings retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"cms_id":{"type":"string","description":"The integration account / tenant identifier"},"cms_type":{"type":"string","description":"Stable integration service identifier"},"name":{"type":"string","nullable":true,"description":"Human-readable integration name"},"integration_type":{"type":"string"},"enabled":{"type":"boolean"},"connection_status":{"type":"string","nullable":true},"auto_invite":{"type":"boolean","nullable":true},"auto_invite_on_activity":{"type":"boolean"},"phase_messages_enabled":{"type":"boolean"},"phase_target":{"type":"string"},"custom_allowed":{"type":"boolean"},"feed":{"nullable":true,"description":"Client-feed settings"},"config":{"nullable":true,"description":"Service-specific mapping, import, sync, and automation settings"},"staff_assignments":{"nullable":true,"description":"Saved staff assignment config, including legacy fields"},"case_type_mappings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type_name":{"type":"string"},"import_id":{"type":"string","nullable":true},"quilia_case_type":{"type":"string","nullable":true},"is_default":{"type":"boolean"},"required_assets":{"nullable":true},"suggested_case_type":{"type":"string","nullable":true},"suggested_confidence":{"type":"number","nullable":true}},"required":["id","type_name","import_id","quilia_case_type","is_default","suggested_case_type","suggested_confidence"]}},"last_event_at":{"type":"string","nullable":true},"last_health_check_at":{"type":"string","nullable":true},"settings_url":{"type":"string","format":"uri"}},"required":["cms_id","cms_type","name","integration_type","enabled","connection_status","auto_invite","auto_invite_on_activity","phase_messages_enabled","phase_target","custom_allowed","case_type_mappings","last_event_at","last_health_check_at","settings_url"]}}},"required":["message","data"]}}}}}}},"/org/integrations/field-mapping-targets":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"List the Quilia fields a CMS field can be mapped to","description":"Quilia's own mapping targets: the case fields a CMS field can fill, and the record types a repeating CMS collection can fill. `accepts` is the kind of value each takes, and `vocabulary`, where present, is the only set of values that column allows — a firm's own label must be mapped onto one of those. `scope` says whether a target is set per project type or once for the whole integration. `contact_destinations` is where a case contact can go: a CMS returns every contact on a case under one endpoint and the firm's own type word is all that distinguishes a treating clinic from a court or a tow yard, so those words are mapped onto these and anything unmapped is not imported. The CMS half of a mapping varies per firm and per project type and is discovered separately.","responses":{"200":{"description":"Mapping targets retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"object","properties":{"target_key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"accepts":{"type":"array","items":{"type":"string"}},"scope":{"type":"string","enum":["projectType","integration"]},"vocabulary":{"type":"array","items":{"type":"string"}}},"required":["target_key","label","description","accepts","scope"]}},"contact_destinations":{"type":"array","items":{"type":"object","properties":{"destination_key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"}},"required":["destination_key","label","description"]}},"records":{"type":"array","items":{"type":"object","properties":{"record_key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"description":{"type":"string"},"accepts":{"type":"array","items":{"type":"string"}},"required":{"type":"boolean"},"vocabulary":{"type":"array","items":{"type":"string"}}},"required":["key","label","description","accepts","required"]}}},"required":["record_key","label","description","fields"]}}},"required":["fields","contact_destinations","records"]}},"required":["data"]}}}}}}},"/org/integrations/{cms_type}/{cms_id}/mappable-fields":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"List the CMS fields a firm can map, for one project type","description":"The firm's own sections and fields, as last read from their CMS, with the Quilia value kind each field can fill and the firm's dropdown values where it has them. Layout fields are excluded: they hold no value and only make the list unreadable.\n\nFor Clio, returns native matter Location and client address state fields for every practice area without a crawl; `discovered_at` is null. Other CMSes return the last crawl, with `discovered_at` indicating when. The portal refreshes it when someone opens the mapping screen or presses Refresh fields. A project type nobody has opened yet returns no sections.","parameters":[{"schema":{"type":"string"},"required":true,"name":"cms_type","in":"path"},{"schema":{"type":"string"},"required":true,"name":"cms_id","in":"path"},{"schema":{"type":"string","description":"CMS project type. Sections and fields are defined per project type."},"required":true,"description":"CMS project type. Sections and fields are defined per project type.","name":"project_type_id","in":"query"}],"responses":{"200":{"description":"Mappable fields retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"project_type_id":{"type":"string"},"discovered_at":{"type":"string","nullable":true},"sections":{"type":"array","items":{"type":"object","properties":{"section_selector":{"type":"string"},"name":{"type":"string"},"is_collection":{"type":"boolean"},"fields":{"type":"array","items":{"type":"object","properties":{"field_selector":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string"},"dropdown_items":{"type":"array","items":{"type":"string"}}},"required":["field_selector","name","kind"]}}},"required":["section_selector","name","is_collection","fields"]}}},"required":["project_type_id","discovered_at","sections"]}},"required":["data"]}}}}}}},"/org/integrations/{cms_type}/{cms_id}":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Update one of the firm's integration configurations","description":"Updates operational integration settings, staff-on-case assignment rules, service-specific config, and CMS-to-Quilia case-type mappings. Requires an organization admin. Credentials, sessions, connection identity, and health fields cannot be changed here.","parameters":[{"schema":{"type":"string"},"required":true,"name":"cms_type","in":"path"},{"schema":{"type":"string"},"required":true,"name":"cms_id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"auto_invite":{"type":"boolean"},"auto_invite_on_activity":{"type":"boolean"},"phase_messages_enabled":{"type":"boolean"},"phase_target":{"type":"string","minLength":1},"custom_allowed":{"type":"boolean"},"feed_enabled":{"type":"boolean"},"config_patch":{"type":"object","additionalProperties":{"nullable":true},"description":"Shallow patch for top-level config keys. A null value removes that key."},"staff_assignments":{"type":"object","nullable":true,"properties":{"mode":{"type":"string","enum":["auto","roles","fields"]},"contactableRoles":{"type":"array","items":{"type":"string"}},"roles":{"type":"object","properties":{"include":{"type":"array","items":{"type":"string"}},"contactable":{"type":"array","items":{"type":"string"}}}},"includeUntitled":{"type":"boolean"},"contactableUntitled":{"type":"boolean"},"fieldSelectors":{"type":"array","items":{"type":"string"}},"sectionSelector":{"type":"string"},"contactableFieldSelectors":{"type":"array","items":{"type":"string"}},"alwaysIncludeUserIds":{"type":"array","items":{"type":"string"}},"alwaysIncludeVisibleToClient":{"type":"boolean"}},"description":"Replace staff-on-case assignment rules; null removes the saved rules."},"field_mapping":{"type":"object","properties":{"project_type_id":{"type":"string","minLength":1,"description":"CMS project type the mapping belongs to. Sections and fields are defined per project type, so a mapping is only valid within one. Omit it for an integration-scoped target, which is set once and applies everywhere."},"target_key":{"type":"string","minLength":1,"description":"Quilia field to fill, from list_field_mapping_targets"},"source":{"type":"object","nullable":true,"properties":{"section_selector":{"type":"string","minLength":1},"field_selector":{"type":"string","minLength":1},"value_map":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"For Clio and Neos case.location only: map the source field's values to existing Quilia location ids. Clio takes matter/location text or client/address.state; Neos takes any case search column, including the client state one. State keys normalize to uppercase codes, and Neos compares on letters and digits so punctuation and casing in a firm's own office names do not matter. Omit to preserve the saved map when the source is unchanged; switching sources starts with an empty map if omitted. An empty object clears it."},"default_location_id":{"type":"integer","nullable":true,"minimum":0,"description":"For Clio and Neos case.location only: existing Quilia location used when the source is blank or unmapped; 0 means the firm primary address. Null clears the fallback. Omit to preserve it when the source is unchanged; changing sources clears an omitted fallback."}},"required":["section_selector","field_selector"],"description":"CMS field to take it from; null clears the mapping."}},"required":["target_key","source"],"description":"Point one Quilia field at one CMS field. Merges into the saved mappings; other targets and other project types are untouched."},"contact_type_mapping":{"type":"object","properties":{"destination_key":{"type":"string","minLength":1,"description":"Where the contacts go, e.g. provider, police-department"},"contact_types":{"type":"array","items":{"type":"string","minLength":1},"description":"The firm's own CMS words for this destination. An empty array clears it. A word may only belong to one destination, so setting it here removes it from any other."}},"required":["destination_key","contact_types"],"description":"Which of the firm's own case-contact types import to which Quilia destination. Nothing imports until mapped: a type absent from every destination is skipped, which is how insurers and police avoid duplicating the rows their own endpoints already write."},"record_mapping":{"type":"object","properties":{"project_type_id":{"type":"string","minLength":1},"record_key":{"type":"string","minLength":1,"description":"Quilia record type, e.g. record.insurance"},"mapping":{"type":"object","nullable":true,"properties":{"section_selector":{"type":"string","minLength":1},"fields":{"type":"object","additionalProperties":{"type":"string"}},"value_maps":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"string"}}}},"required":["section_selector","fields"],"description":"Null clears the record mapping."}},"required":["project_type_id","record_key","mapping"],"description":"Map a repeating CMS collection to a Quilia record type, including what each of the firm's own values means in Quilia."},"subtype_mapping":{"type":"object","properties":{"project_type_id":{"type":"string","minLength":1},"source":{"type":"object","nullable":true,"properties":{"section_selector":{"type":"string","minLength":1},"field_selector":{"type":"string","minLength":1}},"required":["section_selector","field_selector"],"description":"Filevine dropdown or multi-select holding the case subtype; null clears the project-type override."}},"required":["project_type_id","source"],"description":"For one Filevine project type, choose the dropdown or multi-select whose values are imported as case subtypes."},"case_type_mappings":{"type":"array","items":{"type":"object","properties":{"integration_case_type_id":{"type":"string"},"quilia_case_type":{"type":"string","nullable":true}},"required":["integration_case_type_id","quilia_case_type"]},"maxItems":100,"description":"Map imported CMS case-type row ids to Quilia case types. Null clears a mapping."}},"description":"Only provided settings are changed; all others are preserved."}}}},"responses":{"200":{"description":"Integration settings updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"cms_id":{"type":"string","description":"The integration account / tenant identifier"},"cms_type":{"type":"string","description":"Stable integration service identifier"},"name":{"type":"string","nullable":true,"description":"Human-readable integration name"},"integration_type":{"type":"string"},"enabled":{"type":"boolean"},"connection_status":{"type":"string","nullable":true},"auto_invite":{"type":"boolean","nullable":true},"auto_invite_on_activity":{"type":"boolean"},"phase_messages_enabled":{"type":"boolean"},"phase_target":{"type":"string"},"custom_allowed":{"type":"boolean"},"feed":{"nullable":true,"description":"Client-feed settings"},"config":{"nullable":true,"description":"Service-specific mapping, import, sync, and automation settings"},"staff_assignments":{"nullable":true,"description":"Saved staff assignment config, including legacy fields"},"case_type_mappings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"type_name":{"type":"string"},"import_id":{"type":"string","nullable":true},"quilia_case_type":{"type":"string","nullable":true},"is_default":{"type":"boolean"},"required_assets":{"nullable":true},"suggested_case_type":{"type":"string","nullable":true},"suggested_confidence":{"type":"number","nullable":true}},"required":["id","type_name","import_id","quilia_case_type","is_default","suggested_case_type","suggested_confidence"]}},"last_event_at":{"type":"string","nullable":true},"last_health_check_at":{"type":"string","nullable":true},"settings_url":{"type":"string","format":"uri"}},"required":["cms_id","cms_type","name","integration_type","enabled","connection_status","auto_invite","auto_invite_on_activity","phase_messages_enabled","phase_target","custom_allowed","case_type_mappings","last_event_at","last_health_check_at","settings_url"]}}},"required":["message","data"]}}}}}}},"/org/switch":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["org"],"summary":"Switch the calling wizard to another organization","description":"Moves the calling Quilia wizard's membership into another organization, so subsequent requests act in that firm's context. Wizard accounts only. A wizard can only move themselves.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"string","minLength":1,"description":"The organization to switch to: either its UUID or its name. A name is matched case-insensitively, exactly first and then as a partial match."}},"required":["organization"],"description":"Move the calling wizard to another organization"}}}},"responses":{"200":{"description":"Organization switched successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The organization now in context"},"name":{"type":"string","nullable":true,"description":"Its display name"},"active":{"type":"boolean","description":"Whether the organization is active"}},"required":["id","name","active"]}},"required":["message","data"]}}}}}}},"/providers":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["providers"],"summary":"Search the firm's provider directory","description":"Searches the firm's reusable provider directory (providers_list) — medical providers and other care entities the firm works with across cases. These are firm-wide directory entries (distinct from a case-only person row); use the returned id to associate one to a case via POST /cases/{id}/providers. Filter by free-text query (matches name), specialty, and entity type.","parameters":[{"schema":{"type":"string","description":"Free-text search matched against the provider name"},"required":false,"description":"Free-text search matched against the provider name","name":"query","in":"query"},{"schema":{"type":"string","description":"Filter by specialty (partial match)"},"required":false,"description":"Filter by specialty (partial match)","name":"specialty","in":"query"},{"schema":{"type":"string","enum":["business","individual"],"description":"Filter by entity type"},"required":false,"description":"Filter by entity type","name":"type","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":100,"description":"Max results (default 50)"},"required":false,"description":"Max results (default 50)","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"description":"Results to skip (default 0)"},"required":false,"description":"Results to skip (default 0)","name":"offset","in":"query"}],"responses":{"200":{"description":"Providers retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The provider directory id (provider_list_id)"},"name":{"type":"string","description":"Display name"},"company_name":{"type":"string","nullable":true,"description":"Company / practice name"},"first_name":{"type":"string","nullable":true,"description":"First name (for person entities)"},"last_name":{"type":"string","nullable":true,"description":"Last name (for person entities)"},"type":{"type":"string","description":"Entity type (e.g. person, company)"},"specialty":{"type":"string","nullable":true,"description":"Specialty (e.g. orthopedics)"},"phone":{"type":"string","nullable":true,"description":"Phone number"},"fax":{"type":"string","nullable":true,"description":"Fax number"},"email":{"type":"string","nullable":true,"description":"Email"},"address_1":{"type":"string","nullable":true,"description":"Street address"},"city":{"type":"string","nullable":true,"description":"City"},"state":{"type":"string","nullable":true,"description":"State"},"zip":{"type":"string","nullable":true,"description":"Postal / ZIP code"},"categories":{"type":"array","items":{"type":"string"},"description":"Provider categories / tags"}},"required":["id","name","company_name","first_name","last_name","type","specialty","phone","fax","email","address_1","city","state","zip","categories"]}},"pagination":{"type":"object","properties":{"limit":{"type":"number"},"offset":{"type":"number"},"total":{"type":"number","nullable":true}},"required":["limit","offset","total"]}},"required":["message","data","pagination"]}}}}}}},"/reports/mcp-bug":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["reports"],"summary":"Report a misbehaving MCP tool","description":"Files a structured bug report about a Quilia MCP tool that returned the wrong result. Intended to be called by an AI assistant on the user's behalf. Submitted text is rejected if it contains anything that identifies a person (email, phone, SSN, date of birth) — report defects generically.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tool_name":{"type":"string","minLength":1,"maxLength":64,"description":"The Quilia MCP tool that misbehaved, e.g. \"find_staff\""},"expected":{"type":"string","minLength":1,"maxLength":2000,"description":"What the tool should have returned or done"},"actual":{"type":"string","minLength":1,"maxLength":2000,"description":"What it actually returned or did"},"arguments_used":{"type":"object","additionalProperties":{"type":"string","maxLength":120},"description":"Argument names mapped to value SHAPES, never values — {\"name\": \"string(5)\"}, not {\"name\": \"Jane Doe\"}"}},"required":["tool_name","expected","actual"]}}}},"responses":{"201":{"description":"Report filed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"filed":{"type":"boolean"}},"required":["filed"]}},"required":["data"]}}}}}}},"/requests":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"List request templates","description":"Retrieves the firm's saved request templates, newest first. Returns each template's fields so a caller can read a form back before editing it or sending it. Soft-deleted templates are excluded.","parameters":[{"schema":{"type":"number","nullable":true,"default":10,"description":"The maximum number of request templates to return."},"required":false,"description":"The maximum number of request templates to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"The number of request templates to skip before starting to return results."},"required":false,"description":"The number of request templates to skip before starting to return results.","name":"offset","in":"query"},{"schema":{"type":"string","enum":["task","form","signature"],"description":"Only return templates of this kind. 'form' is a built field list, 'signature' places signatures on an uploaded document, 'task' asks the client to do something."},"required":false,"description":"Only return templates of this kind. 'form' is a built field list, 'signature' places signatures on an uploaded document, 'task' asks the client to do something.","name":"type","in":"query"}],"responses":{"200":{"description":"List of request templates retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the request template"},"title":{"type":"string","description":"The title of the request template"},"description":{"type":"string","description":"The description of the request template"},"type":{"type":"string","description":"'form' is a built field list, 'signature' places signatures on an uploaded document, 'task' asks the client to do something"},"generate_pdf_on_completion":{"type":"boolean","description":"Whether a PDF is produced when a client completes it"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the field"},"type":{"type":"string","enum":["text","textarea","file","select","date","time","datetime","signature","richtext","ssn"],"description":"The kind of answer this field takes"},"label":{"type":"string","description":"The question, as the client reads it"},"description":{"type":"string","description":"Helper text shown under the question"},"placeholder":{"type":"string","description":"Placeholder text inside the input"},"required":{"type":"boolean","description":"Whether the client must answer"},"options":{"type":"array","items":{"type":"string"},"description":"The choices for a 'select' field"}},"required":["id","type","label","required"]},"description":"The template fields, in display order"},"created_by":{"type":"string","description":"The user ID of the template creator"},"created_at":{"type":"string","description":"ISO timestamp when the template was created"},"builder_url":{"type":"string","description":"Portal link to open this template in the form builder"}},"required":["id","title","description","type","generate_pdf_on_completion","fields","created_by","created_at","builder_url"]},"description":"Array of request templates"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/requests/templates":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"Create a request form template","description":"Builds a reusable form the firm can send to clients — the same thing the portal's form builder produces. Field ids are assigned server-side; describe each field by type, label and whether it is required. The template is saved to the firm's library and can be sent with POST /requests/send.","requestBody":{"required":true,"description":"The form to build","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"The template title"},"description":{"type":"string","default":"","description":"Instructions shown to the client above the fields"},"fields":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","textarea","file","select","date","time","datetime","signature","richtext","ssn"],"description":"The kind of answer this field takes. 'select' needs `options`; 'file' asks the client to upload; 'signature' captures a signature; 'ssn' encrypts the answer onto the client's own record and stores nothing on the submission, so only one per form is captured and it always belongs to the client filling it."},"label":{"type":"string","minLength":1,"description":"The question, as the client will read it"},"description":{"type":"string","description":"Helper text shown under the question"},"placeholder":{"type":"string","description":"Placeholder text inside the input"},"required":{"type":"boolean","default":false,"description":"Whether the client must answer before submitting"},"options":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"The choices for a 'select' field"}},"required":["type","label"]},"minItems":1,"description":"The fields, in the order the client will see them"},"generate_pdf_on_completion":{"type":"boolean","default":false,"description":"Produce a PDF of the client's answers when they complete it"},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"The language code"},"title":{"type":"string","description":"The translated title"},"description":{"type":"string","description":"The translated instructions"},"fields":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","description":"The translated question"},"description":{"type":"string","description":"Translated helper text"},"placeholder":{"type":"string","description":"Translated placeholder text"},"options":{"type":"array","items":{"type":"string"},"description":"Translated choices for a 'select' field"}},"required":["label"]},"description":"Translated fields, matching the order of the base fields array"}},"required":["language"]},"description":"Translations for this form template"}},"required":["title","fields"]},"examples":{"headacheDiary":{"summary":"A symptom diary","value":{"title":"Headache Diary","description":"Fill this out each time you get a headache, as close to the time as you can.","fields":[{"type":"date","label":"Date of the headache","required":true},{"type":"select","label":"How bad was the pain?","required":true,"options":["1-3 mild","4-6 moderate","7-10 severe"]},{"type":"textarea","label":"What were you doing beforehand?","description":"Anything you noticed — screens, noise, skipped meals, poor sleep."},{"type":"text","label":"Medication taken"}],"generate_pdf_on_completion":true}}}}}},"responses":{"201":{"description":"Form template created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the template"},"title":{"type":"string","description":"The template title"},"description":{"type":"string","description":"The template description / instructions"},"type":{"type":"string","description":"'form' is a built field list, 'signature' places signatures on an uploaded document, 'task' asks the client to do something"},"generate_pdf_on_completion":{"type":"boolean","description":"Whether a PDF is produced when a client completes it"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the field"},"type":{"type":"string","enum":["text","textarea","file","select","date","time","datetime","signature","richtext","ssn"],"description":"The kind of answer this field takes"},"label":{"type":"string","description":"The question, as the client reads it"},"description":{"type":"string","description":"Helper text shown under the question"},"placeholder":{"type":"string","description":"Placeholder text inside the input"},"required":{"type":"boolean","description":"Whether the client must answer"},"options":{"type":"array","items":{"type":"string"},"description":"The choices for a 'select' field"}},"required":["id","type","label","required"]},"description":"The fields, in display order"},"created_by":{"type":"string","description":"The user ID of the template creator"},"created_at":{"type":"string","description":"ISO timestamp when the template was created"},"builder_url":{"type":"string","description":"Portal link to open this template in the form builder"},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"The language code"},"title":{"type":"string","description":"The translated title"},"description":{"type":"string","description":"The translated instructions"},"fields":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","description":"The translated question"},"description":{"type":"string","description":"Translated helper text"},"placeholder":{"type":"string","description":"Translated placeholder text"},"options":{"type":"array","items":{"type":"string"},"description":"Translated choices for a 'select' field"}},"required":["label"]},"description":"Translated fields, matching the order of the base fields array"}},"required":["language"]},"description":"Translations for this form template"}},"required":["id","title","description","type","generate_pdf_on_completion","fields","created_by","created_at","builder_url"]}},"required":["message","data"]}}}}}}},"/requests/templates/{id}":{"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"Update a request form template","description":"Edits a form template in the firm's library. Use `append_fields` to add questions without disturbing the ones already there; use `fields` to replace the list outright when reordering or removing. Sending both is refused — they disagree about what the form should end up as. Templates already sent to clients keep the copy they were sent with, so editing does not rewrite a form somebody is midway through.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The template to update"},"required":true,"description":"The template to update","name":"id","in":"path"}],"requestBody":{"required":true,"description":"The changes to make","content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","minLength":1,"description":"A new title"},"description":{"type":"string","description":"New instructions"},"fields":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","textarea","file","select","date","time","datetime","signature","richtext","ssn"],"description":"The kind of answer this field takes. 'select' needs `options`; 'file' asks the client to upload; 'signature' captures a signature; 'ssn' encrypts the answer onto the client's own record and stores nothing on the submission, so only one per form is captured and it always belongs to the client filling it."},"label":{"type":"string","minLength":1,"description":"The question, as the client will read it"},"description":{"type":"string","description":"Helper text shown under the question"},"placeholder":{"type":"string","description":"Placeholder text inside the input"},"required":{"type":"boolean","default":false,"description":"Whether the client must answer before submitting"},"options":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"The choices for a 'select' field"}},"required":["type","label"]},"minItems":1,"description":"Replaces the entire field list. Send every field you want the template to end up with, in order — anything omitted is removed."},"append_fields":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["text","textarea","file","select","date","time","datetime","signature","richtext","ssn"],"description":"The kind of answer this field takes. 'select' needs `options`; 'file' asks the client to upload; 'signature' captures a signature; 'ssn' encrypts the answer onto the client's own record and stores nothing on the submission, so only one per form is captured and it always belongs to the client filling it."},"label":{"type":"string","minLength":1,"description":"The question, as the client will read it"},"description":{"type":"string","description":"Helper text shown under the question"},"placeholder":{"type":"string","description":"Placeholder text inside the input"},"required":{"type":"boolean","default":false,"description":"Whether the client must answer before submitting"},"options":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"description":"The choices for a 'select' field"}},"required":["type","label"]},"minItems":1,"description":"Adds these fields to the end, leaving the existing ones untouched. Use this to add a question rather than resending the whole form."},"generate_pdf_on_completion":{"type":"boolean","description":"Whether to produce a PDF on completion"},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"The language code"},"title":{"type":"string","description":"The translated title"},"description":{"type":"string","description":"The translated instructions"},"fields":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","description":"The translated question"},"description":{"type":"string","description":"Translated helper text"},"placeholder":{"type":"string","description":"Translated placeholder text"},"options":{"type":"array","items":{"type":"string"},"description":"Translated choices for a 'select' field"}},"required":["label"]},"description":"Translated fields, matching the order of the base fields array"}},"required":["language"]},"description":"Translations to replace existing translations"}}},"examples":{"addAQuestion":{"summary":"Add one question to an existing form","value":{"append_fields":[{"type":"select","label":"How many hours did you sleep?","required":true,"options":["under 4","4-6","6-8","over 8"]}]}},"rename":{"summary":"Retitle without touching the fields","value":{"title":"Carbon Monoxide Intake (2026)"}}}}}},"responses":{"200":{"description":"Form template updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the template"},"title":{"type":"string","description":"The template title"},"description":{"type":"string","description":"The template description / instructions"},"type":{"type":"string","description":"'form' is a built field list, 'signature' places signatures on an uploaded document, 'task' asks the client to do something"},"generate_pdf_on_completion":{"type":"boolean","description":"Whether a PDF is produced when a client completes it"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the field"},"type":{"type":"string","enum":["text","textarea","file","select","date","time","datetime","signature","richtext","ssn"],"description":"The kind of answer this field takes"},"label":{"type":"string","description":"The question, as the client reads it"},"description":{"type":"string","description":"Helper text shown under the question"},"placeholder":{"type":"string","description":"Placeholder text inside the input"},"required":{"type":"boolean","description":"Whether the client must answer"},"options":{"type":"array","items":{"type":"string"},"description":"The choices for a 'select' field"}},"required":["id","type","label","required"]},"description":"The fields, in display order"},"created_by":{"type":"string","description":"The user ID of the template creator"},"created_at":{"type":"string","description":"ISO timestamp when the template was created"},"builder_url":{"type":"string","description":"Portal link to open this template in the form builder"},"translations":{"type":"array","items":{"type":"object","properties":{"language":{"type":"string","enum":["es","pt","ht","km","ko","th","tl","vi","zh_CN","zh_TW","ru","hy","ar","fa","de","pl","it","ja","sr","fr","hmn","mn","hi","pa"],"description":"The language code"},"title":{"type":"string","description":"The translated title"},"description":{"type":"string","description":"The translated instructions"},"fields":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string","description":"The translated question"},"description":{"type":"string","description":"Translated helper text"},"placeholder":{"type":"string","description":"Translated placeholder text"},"options":{"type":"array","items":{"type":"string"},"description":"Translated choices for a 'select' field"}},"required":["label"]},"description":"Translated fields, matching the order of the base fields array"}},"required":["language"]},"description":"Translations for this form template"}},"required":["id","title","description","type","generate_pdf_on_completion","fields","created_by","created_at","builder_url"]}},"required":["message","data"]}}}}}}},"/requests/send":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"Create and send a request (existing template, or a freeform task)","description":"Sends a request to a client in a case. Provide a `templateId` to send an existing form / signature / task-list template, OR `type: \"task\"` with a `title` (+ optional description / url) to create and send a freeform one-off action task with no template. The request is created with 'pending' status and the client is notified. All caller-supplied IDs are verified against the authenticated org.","requestBody":{"required":true,"description":"Either a templated send (templateId) or a freeform task.","content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"templateId":{"type":"string","description":"The ID of an existing request template to send"},"recipientId":{"type":"string","description":"The user ID of the client who will receive the request"},"senderId":{"type":"string","description":"The user ID of the staff member sending the request"},"caseId":{"type":"string","description":"The case ID to associate with this request"}},"required":["templateId","recipientId","senderId","caseId"]},{"type":"object","properties":{"type":{"type":"string","enum":["task"],"description":"Create a freeform one-off action task (no template required)"},"title":{"type":"string","minLength":1,"description":"The task title shown to the client"},"description":{"type":"string","description":"Optional instructions shown with the task"},"url":{"type":"string","format":"uri","description":"Optional http(s) link the client is sent to"},"recipientId":{"type":"string","description":"The user ID of the client who will receive the request"},"senderId":{"type":"string","description":"The user ID of the staff member sending the request"},"caseId":{"type":"string","description":"The case ID to associate with this request"}},"required":["type","title","recipientId","senderId","caseId"]}]}}}},"responses":{"200":{"description":"Request sent successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the send operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the sent request"},"status":{"type":"string","description":"The status of the request (typically 'pending')"}},"required":["id","status"]}},"required":["message","data"]}}}}}}},"/requests/list":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"List a case's requests","description":"Lists the requests sent on a case — summaries only (no response payload). Filter by status and type. Fetch GET /requests/{type}/{id} for a request's full detail + response.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The case to list requests for"},"required":true,"description":"The case to list requests for","name":"caseId","in":"query"},{"schema":{"type":"string","description":"Filter by status (e.g. 'pending', 'completed')"},"required":false,"description":"Filter by status (e.g. 'pending', 'completed')","name":"status","in":"query"},{"schema":{"type":"string","enum":["task","form","signature"],"description":"Filter by request type (task / form / signature)"},"required":false,"description":"Filter by request type (task / form / signature)","name":"type","in":"query"},{"schema":{"type":"number","nullable":true,"default":25,"description":"The maximum number of requests to return."},"required":false,"description":"The maximum number of requests to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"The number of requests to skip before returning results."},"required":false,"description":"The number of requests to skip before returning results.","name":"offset","in":"query"}],"responses":{"200":{"description":"Requests retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the request"},"type":{"type":"string","description":"The request type (task / form / signature)"},"status":{"type":"string","description":"The request status (e.g. 'pending', 'completed')"},"title":{"type":"string","description":"The request title"},"case_id":{"type":"string","description":"The case this request belongs to"},"recipient_id":{"type":"string","nullable":true,"description":"The client the request was sent to"},"task_list_id":{"type":"string","nullable":true,"description":"The parent task list id, if this request is part of one"},"created_at":{"type":"string","description":"ISO timestamp when the request was created"},"submitted_at":{"type":"string","nullable":true,"description":"ISO timestamp when the client completed it, if completed"}},"required":["id","type","status","title","case_id","recipient_id","task_list_id","created_at","submitted_at"]},"description":"Array of request summaries"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/requests/{requestId}/responses":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"Get request response by request ID","description":"Retrieves the response submission for a specific request. Returns the most recent submission if multiple exist. Returns 404 if the request doesn't exist or has no submission.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the request to retrieve responses for"},"required":true,"description":"The unique identifier of the request to retrieve responses for","name":"requestId","in":"path"}],"responses":{"200":{"description":"Request response retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the submission"},"request_id":{"type":"string","description":"The ID of the request this submission belongs to"},"template_id":{"type":"string","description":"The ID of the template used for this request"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the field"},"type":{"type":"string","description":"The type of the field (e.g., 'text', 'file', 'select')"},"label":{"type":"string","description":"The label of the field"},"value":{"type":"string","description":"The value entered by the user"},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The storage path of the file"},"name":{"type":"string","description":"The original filename"},"type":{"type":"string","description":"The MIME type of the file"}},"required":["path","name","type"]},"description":"Array of uploaded files (for file type fields)"}},"required":["id","type"]},"description":"Array of field responses submitted by the client"},"submitted_at":{"type":"string","description":"ISO timestamp when the submission was created"},"duration":{"type":"number","description":"Time taken to complete the submission in milliseconds"},"platform":{"type":"string","description":"Platform where the submission was made (e.g., 'web', 'mobile')"},"request":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the request"},"status":{"type":"string","description":"The status of the request (e.g., 'pending', 'completed')"},"case_id":{"type":"string","description":"The ID of the case associated with this request"},"created_at":{"type":"string","description":"ISO timestamp when the request was created"}},"required":["id","status","case_id","created_at"]},"template":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the template"},"title":{"type":"string","description":"The title of the template"},"description":{"type":"string","description":"The description of the template"}},"required":["id","title","description"]}},"required":["id","request_id","template_id","fields","submitted_at","duration","platform","request","template"],"description":"The request response data"}},"required":["message","data"]}}}}}}},"/requests/responses/{clientId}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"List request responses by client ID","description":"Retrieves a paginated list of all request responses submitted by a specific client. Returns full response data including submission details, related request information, and template metadata.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the client (user_id) to retrieve responses for"},"required":true,"description":"The unique identifier of the client (user_id) to retrieve responses for","name":"clientId","in":"path"},{"schema":{"type":"number","nullable":true,"default":10,"description":"The maximum number of request responses to return."},"required":false,"description":"The maximum number of request responses to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"The number of request responses to skip before starting to return results."},"required":false,"description":"The number of request responses to skip before starting to return results.","name":"offset","in":"query"}],"responses":{"200":{"description":"List of request responses retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the submission"},"request_id":{"type":"string","description":"The ID of the request this submission belongs to"},"template_id":{"type":"string","description":"The ID of the template used for this request"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the field"},"type":{"type":"string","description":"The type of the field (e.g., 'text', 'file', 'select')"},"label":{"type":"string","description":"The label of the field"},"value":{"type":"string","description":"The value entered by the user"},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The storage path of the file"},"name":{"type":"string","description":"The original filename"},"type":{"type":"string","description":"The MIME type of the file"}},"required":["path","name","type"]},"description":"Array of uploaded files (for file type fields)"}},"required":["id","type"]},"description":"Array of field responses submitted by the client"},"submitted_at":{"type":"string","description":"ISO timestamp when the submission was created"},"duration":{"type":"number","description":"Time taken to complete the submission in milliseconds"},"platform":{"type":"string","description":"Platform where the submission was made (e.g., 'web', 'mobile')"},"request":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the request"},"status":{"type":"string","description":"The status of the request (e.g., 'pending', 'completed')"},"case_id":{"type":"string","description":"The ID of the case associated with this request"},"created_at":{"type":"string","description":"ISO timestamp when the request was created"}},"required":["id","status","case_id","created_at"]},"template":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the template"},"title":{"type":"string","description":"The title of the template"},"description":{"type":"string","description":"The description of the template"}},"required":["id","title","description"]}},"required":["id","request_id","template_id","fields","submitted_at","duration","platform","request","template"]},"description":"Array of request responses"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/requests/{id}/resend":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"Resend a request notification","description":"Re-fires the client notification for a pending request — a nudge. Only pending, standalone requests can be resent (task-list items are notified at the list level).","parameters":[{"schema":{"type":"string","format":"uuid","description":"The request id to resend"},"required":true,"description":"The request id to resend","name":"id","in":"path"}],"responses":{"200":{"description":"Notification resent successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the resend"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the request"},"status":{"type":"string","description":"The request status"}},"required":["id","status"]}},"required":["message","data"]}}}}}}},"/requests/{type}/{id}":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["requests"],"summary":"Get a request by type and id","description":"Retrieves a single request by id, namespaced by type. Returns the request's status and — once the client has completed it — the response payload (form fields / signed document) plus any completion note. 404 if the id doesn't exist in this org or isn't of the given type. (Task lists are a separate resource — a request is an item, not a list.)","parameters":[{"schema":{"type":"string","enum":["task","form","signature"],"description":"The request type (task / form / signature)"},"required":true,"description":"The request type (task / form / signature)","name":"type","in":"path"},{"schema":{"type":"string","format":"uuid","description":"The request id"},"required":true,"description":"The request id","name":"id","in":"path"}],"responses":{"200":{"description":"Request retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the request"},"type":{"type":"string","description":"The request type (task / form / signature)"},"status":{"type":"string","description":"The request status (e.g. 'pending', 'completed')"},"title":{"type":"string","description":"The request title"},"description":{"type":"string","nullable":true,"description":"The request instructions / description"},"case_id":{"type":"string","description":"The case this request belongs to"},"recipient_id":{"type":"string","nullable":true,"description":"The client the request was sent to"},"created_at":{"type":"string","description":"ISO timestamp when the request was created"},"submitted_at":{"type":"string","nullable":true,"description":"ISO timestamp when the client completed it, if completed"},"completion_note":{"type":"string","nullable":true,"description":"Optional note the client left when completing a task"},"response":{"type":"object","nullable":true,"properties":{"submitted_at":{"type":"string","description":"ISO timestamp of the submission"},"fields":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the field"},"type":{"type":"string","description":"The type of the field (e.g., 'text', 'file', 'select')"},"label":{"type":"string","description":"The label of the field"},"value":{"type":"string","description":"The value entered by the user"},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The storage path of the file"},"name":{"type":"string","description":"The original filename"},"type":{"type":"string","description":"The MIME type of the file"}},"required":["path","name","type"]},"description":"Array of uploaded files (for file type fields)"}},"required":["id","type"]},"description":"The fields the client submitted"}},"required":["submitted_at","fields"],"description":"The client submission (form / signature), null until completed"}},"required":["id","type","status","title","description","case_id","recipient_id","created_at","submitted_at","completion_note","response"]}},"required":["message","data"]}}}}}}},"/search":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["search"],"operationId":"searchUsers","summary":"Search users","description":"Search for users (all roles) within the authenticated organization.\n\nThis endpoint provides fuzzy search across all organization members including clients, staff, attorneys, and other roles. Results are returned in order of membership creation date (most recent first).\n\n## Search Behavior\n\nThe search query (`q` parameter) performs **case-insensitive partial matching** against multiple user fields simultaneously. If a UUID is provided, an exact match is attempted against the user ID.\n\n## Searchable Fields\n\n| Field | Match Type | Description |\n|-------|------------|-------------|\n| `id` | Exact | User's UUID |\n| `name` | Partial | Full name |\n| `name_first` | Partial | First name |\n| `name_last` | Partial | Last name |\n| `email` | Partial | Email address |\n| `phone` | Partial | Phone number |\n| `address_1` | Partial | Address line 1 |\n| `address_2` | Partial | Address line 2 |\n| `city` | Partial | City |\n| `state` | Partial | State/province |\n| `postal_code` | Partial | Postal/zip code |\n| `country` | Partial | Country |\n\n## Filtering\n\nUse `filter[field]` query parameters to narrow results:\n\n- **`filter[role]`** - Filter by user role. Supports comma-separated values for OR matching.\n- **`filter[active]`** - Filter by active status (`true` or `false`).\n- **`filter[created_at]`** - Filter by membership creation date (supports wildcards).\n- **`filter[updated_at]`** - Filter by membership update date (supports wildcards).\n\n## Examples\n\n```\n# Search for users named \"John\"\nGET /v2/search?q=john\n\n# Search for users in Chicago\nGET /v2/search?q=chicago\n\n# Search for clients only\nGET /v2/search?q=john&filter[role]=client\n\n# Search for active attorneys or legal staff\nGET /v2/search?q=john&filter[role]=attorney,legal staff&filter[active]=true\n\n# Paginate results\nGET /v2/search?q=john&limit=20&offset=40\n```","parameters":[{"schema":{"type":"string","minLength":2,"description":"Search query string (minimum 2 characters). Searches across multiple user fields using case-insensitive partial matching.\n\n**Searched fields:**\n- `id` - Exact UUID match only\n- `name`, `name_first`, `name_last` - Full and partial names\n- `email` - Email address\n- `phone` - Phone number\n- `address_1`, `address_2` - Address lines\n- `city`, `state`, `postal_code`, `country` - Location fields\n\n**Examples:**\n- `q=john` - Matches \"John Doe\", \"johnny@email.com\", etc.\n- `q=chicago` - Matches users in Chicago\n- `q=14aec6c6-9562-4990-9f66-7411187c4d27` - Exact user ID match","example":"john"},"required":true,"name":"q","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":50,"default":10,"description":"Maximum number of results to return (1-50, default 10)","example":10},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of results to skip for pagination","example":0},"required":false,"name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter by user role. Supports comma-separated values for OR matching.\n\n**Valid values:** wizard, admin, attorney, client, legal staff, provider, provider admin, medical staff, third party, wizard-finance\n\n**Examples:**\n- `filter[role]=client` - Only clients\n- `filter[role]=client,attorney` - Clients OR attorneys","example":"client,attorney"},"required":false,"name":"filter[role]","in":"query"},{"schema":{"type":"string","description":"Filter by active status within the organization.\n\n**Valid values:** `true`, `false`\n\n**Examples:**\n- `filter[active]=true` - Only active members\n- `filter[active]=false` - Only inactive members","example":"true"},"required":false,"name":"filter[active]","in":"query"},{"schema":{"type":"string","description":"Filter by membership creation date. Supports wildcards (*) for partial matching.\n\n**Examples:**\n- `filter[created_at]=2024*` - Created in 2024\n- `filter[created_at]=2024-01*` - Created in January 2024","example":"2024*"},"required":false,"name":"filter[created_at]","in":"query"},{"schema":{"type":"string","description":"Filter by membership last updated date. Supports wildcards (*) for partial matching.\n\n**Examples:**\n- `filter[updated_at]=2024*` - Updated in 2024\n- `filter[updated_at]=2024-01*` - Updated in January 2024","example":"2024*"},"required":false,"name":"filter[updated_at]","in":"query"}],"responses":{"200":{"description":"Search completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message indicating the search completed","example":"Search completed"},"data":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","description":"Unique identifier of the user (UUID)","example":"14aec6c6-9562-4990-9f66-7411187c4d27"},"member_id":{"type":"string","description":"Organization membership ID (organization_members.id). Use this to reference the user within the organization context.","example":"25bfd7d7-a673-5a01-a077-8c22298d5e38"},"name":{"type":"string","nullable":true,"description":"User's full name","example":"John Doe"},"name_first":{"type":"string","nullable":true,"description":"User's first name","example":"John"},"name_last":{"type":"string","nullable":true,"description":"User's last name","example":"Doe"},"email":{"type":"string","nullable":true,"description":"User's email address","example":"john.doe@example.com"},"phone":{"type":"string","nullable":true,"description":"User's phone number","example":"+1234567890"},"address_1":{"type":"string","nullable":true,"description":"First line of the user's address","example":"123 Main Street"},"address_2":{"type":"string","nullable":true,"description":"Second line of the user's address (apartment, suite, etc.)","example":"Suite 100"},"city":{"type":"string","nullable":true,"description":"User's city","example":"Chicago"},"state":{"type":"string","nullable":true,"description":"User's state or province","example":"IL"},"postal_code":{"type":"string","nullable":true,"description":"User's postal/zip code","example":"60601"},"country":{"type":"string","nullable":true,"description":"User's country","example":"USA"},"role":{"type":"string","nullable":true,"enum":["wizard","admin","attorney","client","legal staff","provider","provider admin","medical staff","third party","wizard-finance"],"description":"User's role within the organization.\n\n**Possible values:** wizard, admin, attorney, client, legal staff, provider, provider admin, medical staff, third party, wizard-finance","example":"client"},"active":{"type":"boolean","description":"Whether the user is currently active in the organization. Inactive users may have been deactivated but not deleted.","example":true},"job_title":{"type":"string","nullable":true,"description":"User's job title (primarily for staff members)","example":"Paralegal"},"profile_image":{"type":"string","nullable":true,"description":"URL to the user's profile image","example":"https://storage.example.com/profiles/user123.jpg"},"matched_field":{"type":"string","description":"The field that matched the search query. Useful for highlighting or understanding why a result was returned.\n\n**Possible values:** id, name, name_first, name_last, email, phone, address_1, address_2, city, state, postal_code, country, unknown","example":"name"},"created_at":{"type":"string","nullable":true,"description":"ISO 8601 timestamp of when the organization membership was created","example":"2024-01-15T10:30:00Z"},"updated_at":{"type":"string","nullable":true,"description":"ISO 8601 timestamp of when the organization membership was last updated","example":"2024-06-20T14:45:00Z"}},"required":["user_id","member_id","name","name_first","name_last","email","phone","address_1","address_2","city","state","postal_code","country","role","active","job_title","profile_image","matched_field","created_at","updated_at"]},"description":"Array of users matching the search query, ordered by membership creation date (most recent first)"}},"required":["results"]},"query":{"type":"string","description":"The search query that was executed (echoed back for reference)","example":"john"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of users matching the search query","example":25},"offset":{"type":"number","description":"Current offset (number of results skipped)","example":0},"limit":{"type":"number","description":"Maximum results returned per page","example":10},"has_more":{"type":"boolean","description":"Whether more results are available beyond the current page. Use offset + limit to fetch the next page.","example":true}},"required":["total","offset","limit","has_more"]}},"required":["message","data","query","pagination"]}}}}}}},"/staff":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["staff"],"summary":"Create a new staff member","description":"Creates a staff member, idempotent on repeat calls for the same email. The `invite` field controls email behavior: `'send'` always sends an invitation email, `'skip'` never does, `'auto'` (default) sends only when the user is new or has never signed in — safe for nightly staff-sync integrations.","requestBody":{"required":true,"description":"Staff member creation data","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The full name of the staff member"},"name_first":{"type":"string","description":"The first name of the staff member"},"name_last":{"type":"string","description":"The last name of the staff member"},"email":{"type":"string","format":"email","description":"The email address of the staff member"},"phone":{"type":"string","description":"The phone number of the staff member"},"job_title":{"type":"string","description":"The job title of the staff member"},"role":{"type":"string","enum":["admin","attorney","legal staff"],"description":"The role of the staff member (admin, attorney, or legal staff)"},"location_id":{"type":"number","description":"The ID of the office location to assign"},"permission_id":{"type":"string","format":"uuid","description":"The ID of the permission set to assign"},"external_id":{"type":"string","description":"The partner's own identifier for this staff member (used for idempotent creation across mutable fields like email)"},"invite":{"type":"string","enum":["send","skip","auto"],"default":"auto","description":"Controls invitation email behavior. `'send'` always sends an invite, even if the user already exists. `'skip'` never sends an invite — silent create for new users, no-op for existing. `'auto'` (default) sends an invite only when the user is net-new OR has never signed in, making it safe for repeated staff-sync calls without spamming active members."}},"required":["name","email","role"]},"examples":{"newAttorney":{"summary":"Onboard a new attorney with auto-invite","value":{"name":"Sam Chen","name_first":"Sam","name_last":"Chen","email":"sam.chen@example.com","phone":"+15555550140","job_title":"Senior Associate","role":"attorney"}},"nightlySyncSilent":{"summary":"Idempotent nightly staff-sync (no invite spam)","value":{"name":"Pat Rivera","email":"pat.rivera@example.com","role":"legal staff","invite":"skip"}}}}}},"responses":{"200":{"description":"Staff member created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the creation operation"},"data":{"type":"object","properties":{"user_id":{"type":"string","description":"The unique identifier of the created staff member"},"member_id":{"type":"string","description":"The organization membership ID of the staff member"}},"required":["user_id","member_id"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["staff"],"summary":"List staff members","description":"Retrieves a paginated list of staff members for the authenticated organization with optional field filtering. Staff members include admins, attorneys, and legal staff (not clients).","parameters":[{"schema":{"type":"number","nullable":true,"minimum":0,"default":10,"description":"The maximum number of staff members to return."},"required":false,"description":"The maximum number of staff members to return.","name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"The number of staff members to skip before starting to return results."},"required":false,"description":"The number of staff members to skip before starting to return results.","name":"offset","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of user fields to include in the response"},"required":false,"description":"Comma-separated list of user fields to include in the response","name":"fields","in":"query"},{"schema":{"type":"string","description":"Filter by name. See endpoint description for syntax."},"required":false,"description":"Filter by name. See endpoint description for syntax.","name":"filter[name]","in":"query"},{"schema":{"type":"string","description":"Filter by email. See endpoint description for syntax."},"required":false,"description":"Filter by email. See endpoint description for syntax.","name":"filter[email]","in":"query"},{"schema":{"type":"string","description":"Filter by role. See endpoint description for syntax."},"required":false,"description":"Filter by role. See endpoint description for syntax.","name":"filter[role]","in":"query"},{"schema":{"type":"string","description":"Filter by active. See endpoint description for syntax."},"required":false,"description":"Filter by active. See endpoint description for syntax.","name":"filter[active]","in":"query"},{"schema":{"type":"string","description":"Filter by location_id. See endpoint description for syntax."},"required":false,"description":"Filter by location_id. See endpoint description for syntax.","name":"filter[location_id]","in":"query"}],"responses":{"200":{"description":"Staff data retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string","description":"The unique identifier of the staff member"},"member_id":{"type":"string","description":"The organization membership ID of the staff member"},"name":{"type":"string","nullable":true,"description":"The staff member's full name"},"name_first":{"type":"string","nullable":true,"description":"The staff member's first name"},"name_last":{"type":"string","nullable":true,"description":"The staff member's last name"},"email":{"type":"string","nullable":true,"description":"The staff member's email address"},"phone":{"type":"string","nullable":true,"description":"The staff member's phone number"},"profile_image":{"type":"string","nullable":true,"description":"URL to the staff member's profile image"},"external_id":{"type":"string","nullable":true,"description":"The partner's own identifier for this staff member, matching organization_members.metadata.external_id"},"role":{"type":"string","nullable":true,"enum":["admin","attorney","legal staff"],"description":"The staff member's role in the organization"},"active":{"type":"boolean","nullable":true,"description":"Whether the staff member is currently active"},"job_title":{"type":"string","nullable":true,"description":"The staff member's job title"},"city":{"type":"string","nullable":true,"description":"The staff member's city"},"state":{"type":"string","nullable":true,"description":"The staff member's state or province"},"country":{"type":"string","nullable":true,"description":"The staff member's country"},"timezone":{"type":"string","nullable":true,"description":"The staff member's IANA timezone"},"bio":{"type":"string","nullable":true,"description":"The staff member's bio — the 'About' field in the portal"},"linkedin":{"type":"string","nullable":true,"description":"The staff member's LinkedIn profile"},"twitter":{"type":"string","nullable":true,"description":"The staff member's X/Twitter profile"},"facebook":{"type":"string","nullable":true,"description":"The staff member's Facebook profile"},"instagram":{"type":"string","nullable":true,"description":"The staff member's Instagram profile"},"location_id":{"type":"number","nullable":true,"description":"The ID of the office location the staff member is assigned to"},"permission_id":{"type":"string","nullable":true,"description":"The ID of the permission set assigned to the staff member"},"created_at":{"type":"string","nullable":true,"description":"When the staff member was created"},"updated_at":{"type":"string","nullable":true,"description":"When the staff member was last updated"}},"required":["user_id","member_id"]},"description":"Array of staff members"},"pagination":{"type":"object","properties":{"total":{"type":"number","description":"Total number of items available"},"offset":{"type":"number","description":"Number of items skipped"},"limit":{"type":"number","description":"Maximum number of items returned"},"has_more":{"type":"boolean","description":"Whether there is more data to fetch"},"previous":{"type":"string","nullable":true,"description":"URL for the previous page of items, if available"},"next":{"type":"string","nullable":true,"description":"URL for the next page of items, if available"}},"required":["total","offset","limit","has_more","previous","next"]}},"required":["message","data","pagination"]}}}}}}},"/staff/{id}":{"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["staff"],"summary":"Delete a staff member","description":"Removes a staff member from the organization. By default, this performs a soft delete (sets active=false). Use soft_delete=false query parameter to permanently remove the organization membership.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the staff member to delete"},"required":true,"description":"The unique identifier of the staff member to delete","name":"id","in":"path"},{"schema":{"type":"boolean","nullable":true,"default":true,"description":"When true (default), deactivates the staff member. When false, permanently removes the organization membership."},"required":false,"description":"When true (default), deactivates the staff member. When false, permanently removes the organization membership.","name":"soft_delete","in":"query"}],"responses":{"200":{"description":"Staff member successfully deleted/deactivated","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the delete operation"}},"required":["message"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["staff"],"summary":"Retrieve a single staff member","description":"Retrieves detailed information for a specific staff member using either user_id or member_id.","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the staff member to retrieve"},"required":true,"description":"The unique identifier of the staff member to retrieve","name":"id","in":"path"}],"responses":{"200":{"description":"Staff member retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"user_id":{"type":"string","description":"The unique identifier of the staff member"},"member_id":{"type":"string","description":"The organization membership ID of the staff member"},"name":{"type":"string","nullable":true,"description":"The staff member's full name"},"name_first":{"type":"string","nullable":true,"description":"The staff member's first name"},"name_last":{"type":"string","nullable":true,"description":"The staff member's last name"},"email":{"type":"string","nullable":true,"description":"The staff member's email address"},"phone":{"type":"string","nullable":true,"description":"The staff member's phone number"},"profile_image":{"type":"string","nullable":true,"description":"URL to the staff member's profile image"},"external_id":{"type":"string","nullable":true,"description":"The partner's own identifier for this staff member, matching organization_members.metadata.external_id"},"role":{"type":"string","nullable":true,"enum":["admin","attorney","legal staff"],"description":"The staff member's role in the organization"},"active":{"type":"boolean","nullable":true,"description":"Whether the staff member is currently active"},"job_title":{"type":"string","nullable":true,"description":"The staff member's job title"},"city":{"type":"string","nullable":true,"description":"The staff member's city"},"state":{"type":"string","nullable":true,"description":"The staff member's state or province"},"country":{"type":"string","nullable":true,"description":"The staff member's country"},"timezone":{"type":"string","nullable":true,"description":"The staff member's IANA timezone"},"bio":{"type":"string","nullable":true,"description":"The staff member's bio — the 'About' field in the portal"},"linkedin":{"type":"string","nullable":true,"description":"The staff member's LinkedIn profile"},"twitter":{"type":"string","nullable":true,"description":"The staff member's X/Twitter profile"},"facebook":{"type":"string","nullable":true,"description":"The staff member's Facebook profile"},"instagram":{"type":"string","nullable":true,"description":"The staff member's Instagram profile"},"location_id":{"type":"number","nullable":true,"description":"The ID of the office location the staff member is assigned to"},"permission_id":{"type":"string","nullable":true,"description":"The ID of the permission set assigned to the staff member"},"created_at":{"type":"string","nullable":true,"description":"When the staff member was created"},"updated_at":{"type":"string","nullable":true,"description":"When the staff member was last updated"}},"required":["user_id","member_id"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["staff"],"summary":"Update staff member information","description":"Updates specific fields of an existing staff member record. Allows modification of user details (name, email, phone, job_title) and membership details (role, active status, location, permissions).","parameters":[{"schema":{"type":"string","format":"uuid","description":"The unique identifier of the staff member to update"},"required":true,"description":"The unique identifier of the staff member to update","name":"id","in":"path"}],"requestBody":{"required":true,"description":"Staff member update data","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"The staff member's full name"},"name_first":{"type":"string","description":"The staff member's first name"},"name_last":{"type":"string","description":"The staff member's last name"},"email":{"type":"string","format":"email","description":"The staff member's email address"},"phone":{"type":"string","nullable":true,"description":"The staff member's phone number"},"job_title":{"type":"string","nullable":true,"description":"The staff member's job title"},"city":{"type":"string","nullable":true,"description":"The staff member's city"},"state":{"type":"string","nullable":true,"description":"The staff member's state or province"},"country":{"type":"string","nullable":true,"description":"The staff member's country"},"timezone":{"type":"string","nullable":true,"description":"The staff member's IANA timezone, e.g. 'America/Denver'"},"bio":{"type":"string","nullable":true,"description":"The staff member's bio — the 'About' field in the portal"},"linkedin":{"type":"string","nullable":true,"description":"The staff member's LinkedIn profile"},"twitter":{"type":"string","nullable":true,"description":"The staff member's X/Twitter profile"},"facebook":{"type":"string","nullable":true,"description":"The staff member's Facebook profile"},"instagram":{"type":"string","nullable":true,"description":"The staff member's Instagram profile"},"avatar_url":{"type":"string","nullable":true,"format":"uri","description":"The staff member's headshot, as a publicly reachable https image URL (PNG, JPG, GIF or WebP, 10MB max) — we download it, resize anything over 1600px, and host our own copy, so the source URL does not have to stay available. Square works best; it is rendered as a circle. Pass null to remove the current photo."},"role":{"type":"string","enum":["admin","attorney","legal staff"],"description":"The staff member's role (must be admin, attorney, or legal staff)"},"active":{"type":"boolean","description":"Whether the staff member is active"},"location_id":{"type":"number","nullable":true,"description":"The ID of the office location"},"permission_id":{"type":"string","nullable":true,"format":"uuid","description":"The ID of the permission set"},"case_id":{"type":"string","format":"uuid","description":"The case ID to update case-level settings for this staff member"},"contactable":{"type":"boolean","description":"Whether the staff member's contact info is visible to clients in the app (requires case_id)"},"allow_messages":{"type":"boolean","description":"Whether the staff member can send messages in this case (requires case_id)"}}},"examples":{"profile":{"summary":"Update staff member's profile fields","value":{"phone":"+15555550140","job_title":"Partner","role":"admin","location_id":2}},"headshot":{"summary":"Set a staff member's photo from a URL","value":{"avatar_url":"https://example.com/team/jordan-reyes.jpg"}},"deactivate":{"summary":"Deactivate a staff member","value":{"active":false}},"perCaseVisibility":{"summary":"Toggle contactable + messaging for one case (requires case_id)","value":{"case_id":"8c1f6d12-3b4a-4a9d-8f0c-1234567890ab","contactable":true,"allow_messages":true}}}}}},"responses":{"200":{"description":"Staff member updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"user_id":{"type":"string","description":"The unique identifier of the updated staff member"},"member_id":{"type":"string","description":"The organization membership ID of the staff member"}},"required":["user_id","member_id"]}},"required":["message","data"]}}}}}}},"/webhooks":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Create a webhook subscription","description":"Creates a new webhook subscription for the authenticated organization. The subscription connects a webhook template to an external endpoint with custom configuration. The system will automatically generate a webhook secret for signature verification.","requestBody":{"required":true,"description":"Webhook subscription creation data","content":{"application/json":{"schema":{"type":"object","properties":{"event_name":{"type":"string","description":"The name of the event to subscribe to (e.g., 'client.action.created')"},"endpoint":{"type":"string","format":"uri","description":"The HTTPS endpoint URL to receive webhook payloads"},"retry_attempts":{"type":"integer","minimum":0,"maximum":5,"default":3,"description":"Number of retry attempts for failed webhook deliveries (0-5)"}},"required":["event_name","endpoint"]},"example":{"event_name":"client.action.created","endpoint":"https://example.com/webhooks/quilia","retry_attempts":3}}}},"responses":{"201":{"description":"Webhook subscription created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the create operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the webhook subscription"},"event_name":{"type":"string","description":"The name of the event subscribed to"},"endpoint":{"type":"string","nullable":true,"format":"uri","description":"Subscription endpoint"},"status":{"type":"string","nullable":true,"enum":["pending","enabled","disabled"],"description":"Status of the webhook subscription: pending, enabled, disabled"},"shared_secret":{"type":"string","nullable":true,"description":"Shared secret to verify the webhook payload"},"retry_attempts":{"type":"integer","minimum":0,"maximum":5,"default":3,"description":"Number of retry attempts for failed webhook deliveries (0-5)"},"created_at":{"type":"string","description":"When the subscription was created"},"updated_at":{"type":"string","nullable":true,"description":"When the subscription was last updated"}},"required":["id","event_name","endpoint","status","shared_secret","created_at","updated_at"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"List webhook subscriptions","description":"Retrieves a list of all webhook subscriptions for the authenticated organization. Returns subscription details including webhook template information, endpoint configuration, and status.","responses":{"200":{"description":"List of webhook subscriptions retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the list operation"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the webhook subscription"},"event_name":{"type":"string","description":"The name of the event subscribed to"},"endpoint":{"type":"string","nullable":true,"format":"uri","description":"Subscription endpoint"},"status":{"type":"string","nullable":true,"enum":["pending","enabled","disabled"],"description":"Status of the webhook subscription: pending, enabled, disabled"},"shared_secret":{"type":"string","nullable":true,"description":"Shared secret to verify the webhook payload"},"retry_attempts":{"type":"integer","minimum":0,"maximum":5,"default":3,"description":"Number of retry attempts for failed webhook deliveries (0-5)"},"created_at":{"type":"string","description":"When the subscription was created"},"updated_at":{"type":"string","nullable":true,"description":"When the subscription was last updated"},"webhook":{"type":"object","properties":{"id":{"type":"string","description":"The webhook template ID"},"name":{"type":"string","nullable":true,"description":"The webhook event name"},"description":{"type":"string","nullable":true,"description":"The webhook description"},"body_schema":{"nullable":true,"description":"JSON schema for the webhook payload"}},"required":["id","name","description"],"description":"The webhook template details"}},"required":["id","event_name","endpoint","status","shared_secret","created_at","updated_at","webhook"]},"description":"Array of webhook subscriptions"}},"required":["message","data"]}}}}}}},"/webhooks/{id}":{"delete":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Delete a webhook subscription","description":"Deletes a webhook subscription for the authenticated organization. This will stop all webhook deliveries for this subscription immediately.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the webhook subscription"},"required":true,"description":"The unique identifier of the webhook subscription","name":"id","in":"path"}],"responses":{"200":{"description":"Webhook subscription deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the delete operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the webhook subscription"},"event_name":{"type":"string","description":"The name of the event subscribed to"},"endpoint":{"type":"string","nullable":true,"format":"uri","description":"Subscription endpoint"}},"required":["id","event_name","endpoint"]}},"required":["message","data"]}}}}}},"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Retrieve a webhook subscription","description":"Retrieves a specific webhook subscription by its ID for the authenticated organization. Returns subscription details including configuration and associated webhook template information.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the webhook subscription"},"required":true,"description":"The unique identifier of the webhook subscription","name":"id","in":"path"}],"responses":{"200":{"description":"Webhook subscription retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the retrieve operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the webhook subscription"},"event_name":{"type":"string","description":"The name of the event subscribed to"},"endpoint":{"type":"string","nullable":true,"format":"uri","description":"Subscription endpoint"},"status":{"type":"string","nullable":true,"enum":["pending","enabled","disabled"],"description":"Status of the webhook subscription: pending, enabled, disabled"},"shared_secret":{"type":"string","nullable":true,"description":"Shared secret to verify the webhook payload"},"retry_attempts":{"type":"integer","minimum":0,"maximum":5,"default":3,"description":"Number of retry attempts for failed webhook deliveries (0-5)"},"created_at":{"type":"string","description":"When the subscription was created"},"updated_at":{"type":"string","nullable":true,"description":"When the subscription was last updated"},"webhook":{"type":"object","properties":{"id":{"type":"string","description":"The webhook template ID"},"name":{"type":"string","nullable":true,"description":"The webhook event name"},"description":{"type":"string","nullable":true,"description":"The webhook description"},"body_schema":{"type":"object","additionalProperties":{"nullable":true},"description":"JSON schema for the webhook payload"},"params":{"nullable":true,"description":"Parameters schema for the webhook"}},"required":["id","name","description","body_schema"],"description":"The webhook template details"}},"required":["id","event_name","endpoint","status","shared_secret","created_at","updated_at","webhook"]}},"required":["message","data"]}}}}}},"patch":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Update a webhook subscription","description":"Updates a webhook subscription's configuration for the authenticated organization. The updated configuration must still conform to the webhook template's params schema.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the webhook subscription"},"required":true,"description":"The unique identifier of the webhook subscription","name":"id","in":"path"}],"requestBody":{"required":true,"description":"Webhook subscription update data","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"type":"string","nullable":true,"format":"uri","description":"Subscription endpoint"},"retry_attempts":{"type":"integer","minimum":0,"maximum":5,"default":3,"description":"Number of retry attempts for failed webhook deliveries (0-5)"},"status":{"type":"string","nullable":true,"enum":["pending","enabled","disabled"],"description":"Status of the webhook subscription: pending, enabled, disabled"}}},"example":{"endpoint":"https://example.com/webhooks/quilia-v2","retry_attempts":5}}}},"responses":{"200":{"description":"Webhook subscription updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"Success message confirming the update operation"},"data":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the webhook subscription"},"event_name":{"type":"string","description":"The name of the event subscribed to"},"endpoint":{"type":"string","nullable":true,"format":"uri","description":"Subscription endpoint"},"status":{"type":"string","nullable":true,"enum":["pending","enabled","disabled"],"description":"Status of the webhook subscription: pending, enabled, disabled"},"shared_secret":{"type":"string","nullable":true,"description":"Shared secret to verify the webhook payload"},"retry_attempts":{"type":"integer","minimum":0,"maximum":5,"default":3,"description":"Number of retry attempts for failed webhook deliveries (0-5)"},"created_at":{"type":"string","description":"When the subscription was created"},"updated_at":{"type":"string","nullable":true,"description":"When the subscription was last updated"}},"required":["id","event_name","endpoint","status","shared_secret","created_at","updated_at"]}},"required":["message","data"]}}}}}}},"/webhooks/events":{"get":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"List available webhook events","description":"Retrieves a list of available webhook events that organizations can subscribe to. Returns event definitions including event names, descriptions, and payload schemas for Quilia outgoing webhooks.","responses":{"200":{"description":"List of available webhook events retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The unique identifier of the webhook event"},"name":{"type":"string","description":"Unique event name identifier"},"description":{"type":"string","nullable":true,"description":"Human-readable description of when this event is triggered"},"body_schema":{"type":"object","nullable":true,"additionalProperties":{"nullable":true},"description":"JSON schema describing the event payload structure"}},"required":["id","name","description","body_schema"]},"description":"Array of available webhook events"}},"required":["data"]}}}}}}},"/webhooks/{id}/regenerate-secret":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Regenerate webhook secret","description":"Regenerates the shared secret for a webhook subscription. This will invalidate the previous secret and generate a new one for signature verification.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the webhook subscription"},"required":true,"description":"The unique identifier of the webhook subscription","name":"id","in":"path"}],"responses":{"200":{"description":"Webhook secret regenerated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"new_secret":{"type":"string"}},"required":["id","new_secret"]}},"required":["data"]}}}}}}},"/webhooks/simulate":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Simulate webhook event","description":"Simulates a webhook event by sending the example payload from the event's schema to a specified endpoint. Useful for testing webhook integrations during development.","requestBody":{"required":true,"description":"Webhook simulation parameters","content":{"application/json":{"schema":{"type":"object","properties":{"event_name":{"type":"string","description":"The name of the webhook event to simulate (e.g., 'document.created', 'case.updated')"},"endpoint":{"type":"string","format":"uri","description":"The endpoint URL to send the simulated webhook to"},"use_example":{"type":"boolean","default":true,"description":"Whether to use the example payload from the schema (default: true)"}},"required":["event_name","endpoint"]},"example":{"event_name":"client.action.created","endpoint":"https://example.com/webhooks/quilia","use_example":true}}}},"responses":{"200":{"description":"Webhook simulation completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Whether the webhook simulation was successful"},"message":{"type":"string","description":"Human-readable message about the simulation result"},"event_name":{"type":"string","description":"The event that was simulated"},"endpoint":{"type":"string","description":"The endpoint that received the webhook"},"payload":{"type":"object","additionalProperties":{"nullable":true},"description":"The payload that was sent"},"response":{"type":"object","properties":{"status":{"type":"number","description":"HTTP status code from the endpoint"},"body":{"type":"string","description":"Response body from the endpoint"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Response headers from the endpoint"}},"required":["status"],"description":"Response details from the endpoint"},"error":{"type":"string","description":"Error message if the simulation failed"}},"required":["success","message","event_name","endpoint","payload"]}}}}}}},"/webhooks/test":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Test webhook endpoint","description":"Tests a webhook endpoint by sending a test payload. Can be used to verify endpoint connectivity before creating a subscription.","requestBody":{"required":true,"description":"Test webhook endpoint data","content":{"application/json":{"schema":{"type":"object","properties":{"endpoint":{"type":"string","format":"uri","description":"The webhook endpoint URL to test"}},"required":["endpoint"]},"example":{"endpoint":"https://example.com/webhooks/quilia"}}}},"responses":{"200":{"description":"Webhook test completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"response":{"type":"string"},"details":{"type":"string"}},"required":["success","message"]}}}}}}},"/webhooks/{id}/test":{"post":{"400":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorBadRequest"}}},"_cached":null}}}},"401":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorUnauthorized"}}},"_cached":null}}}},"402":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorPaymentRequired"}}},"_cached":null}}}},"403":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorForbidden"}}},"_cached":null}}}},"404":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorNotFound"}}},"_cached":null}}}},"405":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorMethodNotAllowed"}}},"_cached":null}}}},"409":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorConflict"}}},"_cached":null}}}},"429":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorTooManyRequests"}}},"_cached":null}}}},"500":{"description":"","content":{"application/json":{"schema":{"_def":{"unknownKeys":"strip","catchall":{"_def":{"typeName":"ZodNever"}},"typeName":"ZodObject","openapi":{"_internal":{"refId":"ErrorInternalServerError"}}},"_cached":null}}}},"tags":["webhooks"],"summary":"Test webhook subscription","description":"Tests a specific webhook subscription by sending a test payload to the configured endpoint. If the endpoint returns a 2xx response, the subscription status will be updated to 'enabled'.","parameters":[{"schema":{"type":"string","description":"The unique identifier of the webhook subscription"},"required":true,"description":"The unique identifier of the webhook subscription","name":"id","in":"path"}],"responses":{"200":{"description":"Webhook subscription test completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"activation":{"type":"boolean"},"response":{"type":"string"},"details":{"type":"string"},"data":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["enabled","pending","disabled"]},"activated_at":{"type":"string"}},"required":["id"]}},"required":["success","message"]}}}}}}}}}