{"openapi":"3.1.0","info":{"title":"ASL Direct Intake Platform API","version":"1.4.0","description":"Management and tenant-scoped data API for the direct Twilio → Node.js → Amazon Nova 2 Sonic legal-intake platform."},"servers":[{"url":"/"}],"tags":[{"name":"Service"},{"name":"Operations"},{"name":"Firms"},{"name":"Voice Configuration"},{"name":"Credentials"},{"name":"Calls"},{"name":"Intakes"},{"name":"Audit"},{"name":"Exports"}],"paths":{"/health":{"get":{"tags":["Service"],"summary":"Liveness","responses":{"200":{"description":"Healthy"}}}},"/ready":{"get":{"tags":["Service"],"summary":"Database readiness","responses":{"200":{"description":"Ready"},"503":{"description":"Not ready"}}}},"/v1/meta":{"get":{"tags":["Service"],"summary":"Service contract and capabilities","responses":{"200":{"description":"Metadata"}}}},"/v1/diagnostics":{"get":{"tags":["Operations"],"summary":"Sanitized runtime diagnostics","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Diagnostics"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/setup":{"get":{"tags":["Operations"],"summary":"Guided setup state","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Setup guide"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/admin/firms":{"get":{"tags":["Firms"],"summary":"List firms","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Firm list"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}},"post":{"tags":["Firms"],"summary":"Create a firm","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFirm"}}}},"responses":{"201":{"description":"Created"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/admin/firms/{firmId}":{"patch":{"tags":["Firms"],"summary":"Update a firm","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Updated"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/admin/firms/{firmId}/voice-agent":{"get":{"tags":["Voice Configuration"],"summary":"Read direct voice configuration","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Voice configuration"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}},"put":{"tags":["Voice Configuration"],"summary":"Create or update direct voice configuration","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceAgentConfig"}}}},"responses":{"200":{"description":"Saved"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}},"delete":{"tags":["Voice Configuration"],"summary":"Deactivate direct voice configuration","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Deactivated"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/admin/firms/{firmId}/api-keys":{"get":{"tags":["Credentials"],"summary":"List API keys","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Keys"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}},"post":{"tags":["Credentials"],"summary":"Create API key","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"201":{"description":"Created; secret shown once"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/firms/{firmId}/calls":{"get":{"tags":["Calls"],"summary":"List calls","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Calls"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/firms/{firmId}/calls/{callId}":{"get":{"tags":["Calls"],"summary":"Read a call with transcript and intake","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"},{"name":"callId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Call"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/firms/{firmId}/intakes":{"get":{"tags":["Intakes"],"summary":"List intakes","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Intakes"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/firms/{firmId}/intakes/{intakeId}":{"get":{"tags":["Intakes"],"summary":"Read an intake","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"},{"name":"intakeId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Intake"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/firms/{firmId}/audit-events":{"get":{"tags":["Audit"],"summary":"List audit events","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"Audit events"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}},"/v1/firms/{firmId}/export/canonical":{"get":{"tags":["Exports"],"summary":"Export canonical lifecycle events as NDJSON","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/FirmId"}],"responses":{"200":{"description":"NDJSON export"},"400":{"description":"Invalid request"},"401":{"description":"Authentication required"},"403":{"description":"Insufficient access"},"404":{"description":"Not found"},"429":{"description":"Rate limited"},"500":{"description":"Internal error"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer"}},"parameters":{"FirmId":{"name":"firmId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}},"schemas":{"CreateFirm":{"type":"object","required":["slug","name","timezone"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"},"status":{"type":"string","enum":["provisioning","pilot","active","suspended","closed"]}}},"VoiceAgentConfig":{"type":"object","required":["twilio_number","prompt_version","system_prompt"],"properties":{"twilio_number":{"type":"string"},"prompt_version":{"type":"string"},"system_prompt":{"type":"string"},"voice_id":{"type":"string"},"transfer_number":{"type":["string","null"]},"practice_areas":{"type":"array","items":{"type":"string"}},"max_call_duration_minutes":{"type":"integer","minimum":5,"maximum":120}}},"ServiceMeta":{"type":"object","properties":{"service":{"const":"asl-direct-intake-platform"},"version":{"const":"1.4.0"},"api_contract_version":{"const":"1.0"},"canonical_schema_version":{"const":"1.0"},"architecture":{"const":"twilio-node-nova"}}}}}}