{"openapi":"3.0.0","info":{"title":"Aila API","version":"1.0.0","description":"Aila is an AI-powered sales automation platform that provides call recording, transcription, analysis, and CRM integration capabilities. This API enables developers to integrate with Aila's core features programmatically.","contact":{"name":"Aila Support","email":"support@aila.fyi","url":"https://aila.fyi"}},"servers":[{"url":"https://app.aila.fyi","description":"Production server"}],"tags":[{"name":"Organizations","description":"Organization management"},{"name":"Users","description":"User and member management"},{"name":"Calls","description":"Call recording, upload, and analysis"},{"name":"Contacts","description":"Contact and lead management"},{"name":"Insights","description":"AI-generated insights and patterns"},{"name":"Live Calls","description":"Real-time call recording via bot integration"},{"name":"Compliance","description":"Compliance checklists and quality assurance"},{"name":"LOS","description":"LOS Partner API. These routes accept an API key only. The loan id is the loan number in the LOS, not the Aila loan file id."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"API Key authentication. Include your API key in the Authorization header as `Bearer YOUR_API_KEY`"}},"schemas":{"Error":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{"type":"object"}}}}},"Pagination":{"type":"object","properties":{"page":{"type":"number"},"limit":{"type":"number"},"total":{"type":"number"},"totalPages":{"type":"number"}}},"Call":{"type":"object","properties":{"id":{"type":"string","example":"ai_call_123"},"organizationId":{"type":"string"},"userId":{"type":"string"},"connectionId":{"type":"string"},"contactId":{"type":"string"},"state":{"type":"string","enum":["uploaded","processing","complete","failed"]},"recordedAt":{"type":"string","format":"date-time"},"stats":{"type":"object","properties":{"durationInSeconds":{"type":"number"},"sizeInMegabytes":{"type":"number"}}},"metadata":{"type":"object","properties":{"contactName":{"type":"string"},"contactNumber":{"type":"string"},"originalFilename":{"type":"string"}}},"contactType":{"type":"string","nullable":true,"description":"Organization-configured contact type identifier, when enabled."},"contactTypeLabel":{"type":"string","nullable":true,"description":"Organization-configured contact type label, when enabled."},"data":{"type":"object","properties":{"base":{"type":"object","properties":{"attributes":{"type":"object","properties":{"summary":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}}},"contact_name":{"type":"object","properties":{"label":{"type":"string"},"value":{"type":"string"}}}}}}}}},"riskLevel":{"type":"string","enum":["none","low","medium","high"]},"reviewStatus":{"type":"string","enum":["pending","reviewed"]},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Organization":{"type":"object","properties":{"id":{"type":"string","example":"ai_organization_123"},"name":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"User":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"name":{"type":"string"},"roles":{"type":"array","items":{"type":"string","enum":["user","admin"]}},"state":{"type":"string","enum":["active","deactivated"]},"industry":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"Contact":{"type":"object","properties":{"id":{"type":"string"},"organizationId":{"type":"string"},"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"company":{"type":"string"},"status":{"type":"string","enum":["open","won","lost"]},"timezone":{"type":"string"},"firstOpportunityCreatedAt":{"type":"string","format":"date-time"},"firstCallAt":{"type":"string","format":"date-time"},"speedToLead":{"type":"object","properties":{"windowStartAt":{"type":"string","format":"date-time"},"firstCallAt":{"type":"string","format":"date-time"},"minutesToFirstCall":{"type":"number"},"slaMet":{"type":"boolean"},"reason":{"type":"string"}}},"createdAt":{"type":"string","format":"date-time"}}},"BatchUploadRequest":{"type":"object","properties":{"calls":{"type":"array","items":{"type":"object","properties":{"audio_url":{"type":"string","format":"uri","description":"URL to the audio file"},"recorded_at":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of when the call occurred"},"agent_name":{"type":"string"},"agent_email":{"type":"string","format":"email"},"contact_name":{"type":"string"},"contact_phone":{"type":"string"},"external_id":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object"}},"required":["audio_url","recorded_at","agent_name","agent_email"]},"minItems":1,"maxItems":100}},"required":["calls"]},"BatchUploadResponse":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"batch_id":{"type":"string"},"total_calls":{"type":"number"},"status":{"type":"string","enum":["queued","processing","completed","failed"]},"calls":{"type":"array","items":{"type":"object","properties":{"call_id":{"type":"string"},"external_id":{"type":"string","nullable":true},"status":{"type":"string","enum":["queued","processing","complete","failed"]}}}},"status_url":{"type":"string","format":"uri"}}}}}}},"paths":{"/api/v1/organizations/{organizationId}":{"get":{"summary":"Get organization details","tags":["Organizations"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"},"description":"Organization ID"}],"responses":{"200":{"description":"Organization details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Organization not found"}}},"patch":{"summary":"Update organization","tags":["Organizations"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}}}}}},"responses":{"200":{"description":"Organization updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}}}}},"/api/v1/users/me":{"get":{"summary":"Get current user","tags":["Users"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current user details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}}},"/api/v1/organizations/{organizationId}/calls":{"get":{"summary":"List calls","description":"Retrieve a paginated list of calls for an organization with optional filters","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"number","default":1}},{"name":"limit","in":"query","schema":{"type":"number","default":50,"maximum":100}},{"name":"state","in":"query","schema":{"type":"string","enum":["uploaded","processing","complete","failed"]}},{"name":"userId","in":"query","schema":{"type":"string"}},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Start date (ISO 8601)"},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"},"description":"End date (ISO 8601)"},{"name":"search","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"List of calls","content":{"application/json":{"schema":{"type":"object","properties":{"calls":{"type":"array","items":{"$ref":"#/components/schemas/Call"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}}}},"post":{"summary":"Upload a call","description":"Upload a single call recording with metadata","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Audio file (MP3, WAV, M4A, or FLAC)"},"connectionId":{"type":"string"},"contactName":{"type":"string"},"contactNumber":{"type":"string"},"recordedAt":{"type":"string","format":"date-time"}},"required":["file"]}}}},"responses":{"201":{"description":"Call uploaded successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}}}}},"/api/v1/calls/{callId}":{"get":{"summary":"Get call details","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"callId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Call details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}}}},"patch":{"summary":"Update call","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"callId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"}},"riskLevel":{"type":"string","enum":["none","low","medium","high"]},"reviewStatus":{"type":"string","enum":["pending","reviewed"]},"reviewNotes":{"type":"string"}}}}}},"responses":{"200":{"description":"Call updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}}}},"delete":{"summary":"Delete call","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"callId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Call deleted"}}}},"/api/v1/calls/{callId}/transcript":{"get":{"summary":"Get call transcript","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"callId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Call transcript","content":{"application/json":{"schema":{"type":"object","properties":{"transcript":{"type":"string"},"diarizedTranscript":{"type":"string"},"identifiedTranscript":{"type":"string"}}}}}}}}},"/api/v1/calls/upload/batch":{"post":{"summary":"Batch upload calls","description":"Upload multiple calls in a single request. Maximum 100 calls per batch.","tags":["Calls"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUploadRequest"}}}},"responses":{"202":{"description":"Batch accepted for processing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchUploadResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/batches/{batchId}":{"get":{"summary":"Get batch upload status","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"batchId","in":"path","required":true,"schema":{"type":"string"},"description":"Batch ID"}],"responses":{"200":{"description":"Batch status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"batch_id":{"type":"string"},"total_calls":{"type":"number"},"processed":{"type":"number"},"failed":{"type":"number"},"in_progress":{"type":"number"},"status":{"type":"string","enum":["queued","processing","completed","failed"]},"progress_percentage":{"type":"number"}}}}}}}}}}},"/api/v1/organizations/{organizationId}/contacts":{"get":{"summary":"List contacts","tags":["Contacts"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"number","default":1}},{"name":"limit","in":"query","schema":{"type":"number","default":50}},{"name":"status","in":"query","schema":{"type":"string","enum":["open","won","lost"]}}],"responses":{"200":{"description":"List of contacts","content":{"application/json":{"schema":{"type":"object","properties":{"contacts":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}}}},"post":{"summary":"Create contact","tags":["Contacts"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"company":{"type":"string"},"status":{"type":"string","enum":["open","won","lost"]}},"required":["firstName","lastName"]}}}},"responses":{"201":{"description":"Contact created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}}}}},"/api/v1/organizations/{organizationId}/contacts/{contactId}/mortgage-application/export/fnma":{"get":{"summary":"Export contact mortgage application as MISMO 3.4 XML","description":"Generates an FNMA MISMO 3.4 XML file from the active mortgage application for a contact. Set `dry_run=1` to validate the export and return a preview without downloading XML.","tags":["Contacts"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"},"description":"Organization ID"},{"name":"contactId","in":"path","required":true,"schema":{"type":"string"},"description":"Contact ID"},{"name":"dry_run","in":"query","required":false,"schema":{"type":"string","enum":["1"]},"description":"Set to `1` to validate and return a JSON preview instead of the XML file."}],"responses":{"200":{"description":"MISMO XML file generated successfully, or validation preview returned when `dry_run=1`.","headers":{"X-FNMA-Warnings":{"description":"JSON-encoded warning messages.","schema":{"type":"string"}},"X-FNMA-Errors":{"description":"JSON-encoded error messages.","schema":{"type":"string"}},"X-FNMA-Has-Errors":{"description":"Whether validation errors were present.","schema":{"type":"string","enum":["true","false"]}}},"content":{"application/xml":{"schema":{"type":"string","description":"FNMA MISMO 3.4 XML document"}},"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"warnings":{"type":"array","items":{"type":"string"}},"errors":{"type":"array","items":{"type":"string"}},"validationWarnings":{"type":"array","items":{"type":"object"}},"validationErrors":{"type":"array","items":{"type":"object"}},"preview":{"type":"array","items":{"type":"object"}},"application":{"type":"object","properties":{"id":{"type":"string"},"contactId":{"type":"string"},"sourceCallIds":{"type":"array","items":{"type":"string"}},"completenessPercent":{"type":"number"}}}}}}}},"401":{"description":"Unauthorized or invalid API key"},"403":{"description":"API key is scoped to a different organization, user lacks access, or FNMA export is unavailable for the organization."},"404":{"description":"Organization, contact, or active mortgage application not found"},"422":{"description":"FNMA data failed validation","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"},"errors":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}},"validationErrors":{"type":"array","items":{"type":"object"}},"validationWarnings":{"type":"array","items":{"type":"object"}}}}}}},"500":{"description":"Error generating FNMA export"}}}},"/api/v1/organizations/{organizationId}/insights":{"get":{"summary":"List insights","description":"Retrieves AI-generated insights from call patterns including questions and objections","tags":["Insights"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100}},{"name":"type","in":"query","schema":{"type":"string","enum":["questions","objections"]},"description":"Filter by insight type"},{"name":"userIds","in":"query","schema":{"type":"string"},"description":"Comma-separated list of user IDs"},{"name":"startDate","in":"query","schema":{"type":"string","format":"date"},"description":"Filter from this date (YYYY-MM-DD)"},{"name":"endDate","in":"query","schema":{"type":"string","format":"date"},"description":"Filter until this date (YYYY-MM-DD)"}],"responses":{"200":{"description":"Insights retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"},"count":{"type":"integer"},"ideal_response":{"type":"string"}}}},"objections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"},"count":{"type":"integer"},"ideal_response":{"type":"string"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}}}}},"/api/v1/organizations/{organizationId}/live-calls":{"get":{"summary":"List live calls","description":"Retrieves all live and recent recording sessions","tags":["Live Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string","enum":["starting","recording","completed","failed","stopped"]}},{"name":"platform","in":"query","schema":{"type":"string","enum":["zoom","teams","meet","phone"]}}],"responses":{"200":{"description":"Live calls retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"liveCalls":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["starting","recording","completed","failed","stopped"]},"platform":{"type":"string","enum":["zoom","teams","meet","phone"]},"meetingUrl":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"duration":{"type":"number"}}}}}}}}}}},"post":{"summary":"Start live call recording","description":"Initiates recording for a live call session","tags":["Live Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["title","platform"],"properties":{"title":{"type":"string"},"platform":{"type":"string","enum":["zoom","teams","meet","phone"]},"meetingUrl":{"type":"string","format":"uri"},"participants":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"type":"string","enum":["host","participant"]}}}}}}}}},"responses":{"201":{"description":"Live call recording started"}}}},"/api/v1/organizations/{organizationId}/calls/{callId}/compliance":{"get":{"summary":"Get call compliance assessments","description":"Retrieves compliance assessments for a specific call","tags":["Compliance"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"callId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Compliance assessments retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"assessments":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"templateId":{"type":"string"},"templateName":{"type":"string"},"totalScore":{"type":"number"},"passingScore":{"type":"number"},"passed":{"type":"boolean"}}}}}}}}}}}},"/api/v1/organizations/{organizationId}/checklist-templates":{"get":{"summary":"List checklist templates","description":"Retrieves compliance assessment templates for an organization","tags":["Compliance"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"page","in":"query","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"isActive","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Checklist templates retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"passingScore":{"type":"number"},"isActive":{"type":"boolean"},"questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"required":{"type":"boolean"},"weight":{"type":"number"}}}}}}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}}}},"post":{"summary":"Create checklist template","description":"Creates a new compliance assessment template","tags":["Compliance"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"passingScore":{"type":"number","default":80},"questions":{"type":"array","items":{"type":"object","required":["text"],"properties":{"text":{"type":"string"},"required":{"type":"boolean","default":true},"weight":{"type":"number","default":1},"criteria":{"type":"string"}}}}}}}}},"responses":{"201":{"description":"Checklist template created"}}}},"/api/v1/organizations/{organizationId}/starred-calls":{"get":{"summary":"List starred calls","description":"Retrieves highlighted/bookmarked calls for training","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Starred calls retrieved"}}},"post":{"summary":"Star a call","description":"Bookmark a call for training or reference","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["callId","reason"],"properties":{"callId":{"type":"string"},"reason":{"type":"string","enum":["training","reference","quality","compliance","best_practice"]},"notes":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"isPublic":{"type":"boolean"}}}}}},"responses":{"201":{"description":"Call starred"}}}},"/api/v1/organizations/{organizationId}/webhooks":{"get":{"summary":"List webhooks","description":"Retrieves all webhook subscriptions","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Webhooks retrieved"}}},"post":{"summary":"Create webhook","description":"Subscribe to real-time event notifications","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","url","eventTypes"],"properties":{"name":{"type":"string"},"url":{"type":"string","format":"uri"},"eventTypes":{"type":"array","items":{"type":"string","enum":["call.completed","call.data.extracted","task.created","task.synced","appointment.created","appointment.synced","mismo.ready","agent.run.finished","test.ping"]}},"active":{"type":"boolean","default":true}}}}}},"responses":{"201":{"description":"Webhook created"}}}},"/api/v1/organizations/{organizationId}/api-keys":{"get":{"summary":"List API keys","description":"Retrieves all API keys for the organization","tags":["API Keys"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"API keys retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["admin","user","readonly"]},"lastUsedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}}}},"post":{"summary":"Create API key","description":"Generate a new API key for server-to-server integration","tags":["API Keys"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"role":{"type":"string","enum":["admin","user","readonly"],"default":"user"}}}}}},"responses":{"201":{"description":"API key created (key only shown once)"}}}},"/api/v1/organizations/{organizationId}/metrics/summary":{"get":{"summary":"Get metrics summary","description":"Retrieves aggregated metrics including call counts, durations, and performance","tags":["Metrics"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"startDate","in":"query","schema":{"type":"string","format":"date"}},{"name":"endDate","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Metrics summary retrieved"}}}},"/api/v1/organizations/{organizationId}/calls/{callId}/analysis":{"get":{"summary":"Get call analysis","description":"Retrieves AI-generated analysis for a call","tags":["Calls"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"callId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Call analysis retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"string"},"sentiment":{"type":"string","enum":["positive","negative","neutral"]},"topics":{"type":"array","items":{"type":"string"}},"actionItems":{"type":"array","items":{"type":"string"}},"riskScore":{"type":"number"}}}}}}}}},"/api/v1/organizations/{organizationId}/los/loans/{loanId}/notes":{"post":{"summary":"Write a loan note","description":"Write one plain-text note into an LOS loan. Requires an API key with los:write. Send Idempotency-Key to make a retry return the first result. A read-only loan returns 409 with a neutral reason and a user count. A timeout returns 503 los_unavailable. A refused sign-in returns 502.","tags":["LOS"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"loanId","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric LOS loan id"},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":1,"maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["text"],"properties":{"text":{"type":"string","minLength":1,"maxLength":10000},"notify":{"type":"boolean"}}}}}},"responses":{"200":{"description":"The note was written, or this key already wrote it.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"noteId":{"type":"string","nullable":true},"loanId":{"type":"string"},"idempotentReplay":{"type":"boolean"}}}}}}}},"400":{"description":"Bad body, bad loan id, or a reused key with a different body"},"403":{"description":"API key or los:write check failed"},"404":{"description":"The LOS could not find this loan"},"409":{"description":"No LOS connection, another write is in progress, or the loan is read-only. A read-only loan sets error.details.reason to loan_open_by_user, loan_status_read_only, closing_started, or unknown. It also sets canUnlock and activeUserCount. The body has a count only. It has no user names."},"429":{"description":"The LOS rate limit rejected the note write"},"502":{"description":"The LOS connection must be reconnected, or the LOS rejected the note. The code is UPSTREAM_ERROR. The reconnect message asks an admin to reconnect the LOS."},"503":{"description":"The LOS did not answer. The code is los_unavailable. Wait for Retry-After, then try the same request again.","headers":{"Retry-After":{"description":"Seconds to wait before a retry","schema":{"type":"integer"}}}},"504":{"description":"The note write timed out and the result is unknown. Check the loan before a retry. The code is UPSTREAM_ERROR."}}}},"/api/v1/organizations/{organizationId}/los/loans/{loanId}/agent-runs":{"post":{"summary":"Start an agent run","description":"Start an agent on the loan file for this LOS loan id. Send the agent slug. The server picks the engine. Poll the GET route with the returned run id, or subscribe a webhook to agent.run.finished. Requires an API key with loan-files:write. A key with * also works.","tags":["LOS"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"loanId","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric LOS loan id"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["agentSlug"],"properties":{"agentSlug":{"type":"string","minLength":1,"maxLength":64},"objective":{"type":"string","minLength":1,"maxLength":4000},"clientRequestKey":{"type":"string","minLength":1,"maxLength":200}}}}}},"responses":{"202":{"description":"The run was accepted. Poll the status route.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"runId":{"type":"string","nullable":true},"agentSlug":{"type":"string"},"engine":{"type":"string","enum":["ledger","v4_pre_approval"]},"status":{"type":"string"},"loanFileId":{"type":"string"},"alreadyRunning":{"type":"boolean"}}}}}}}},"400":{"description":"Bad body, bad loan id, or unknown agent"},"403":{"description":"API key, permission, or loan files check failed"},"404":{"description":"No loan file for this loan id, or the key owner cannot open it"},"409":{"description":"The agent already has an active task on this file, or the clientRequestKey was used before"},"429":{"description":"Too many agent starts for this API key: 10 per minute and 100 per hour. details.retryAfterSeconds gives the wait"},"500":{"description":"Server error. If the workflow did not start, the run is marked failed"}}}},"/api/v1/organizations/{organizationId}/los/loans/{loanId}/agent-runs/{runId}":{"get":{"summary":"Read an agent run","description":"Read the status and the report of one agent run on this LOS loan. The run id prefix picks the engine. Requires an API key with loan-files:read. loan-files:write and * also work.","tags":["LOS"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"loanId","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric LOS loan id"},{"name":"runId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Run status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"runId":{"type":"string"},"agentSlug":{"type":"string"},"engine":{"type":"string","enum":["ledger","v4_pre_approval"]},"status":{"type":"string"},"done":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"reportMarkdown":{"type":"string","nullable":true,"description":"The agent report as markdown. Null until the run is done and wrote a report."}}}}}}}},"400":{"description":"Bad loan id"},"403":{"description":"API key, permission, or loan files check failed"},"404":{"description":"No loan file, or the run is not on this loan"}}}},"/api/v1/organizations/{organizationId}/los/loans/{loanId}/agent-reports":{"get":{"summary":"Read the latest agent reports","description":"Read the latest report of each agent on this LOS loan, newest first. Only complete and partially complete runs with a report are included. Send agentSlug to get only that agent. Requires an API key with loan-files:read. loan-files:write and * also work.","tags":["LOS"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"organizationId","in":"path","required":true,"schema":{"type":"string"}},{"name":"loanId","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric LOS loan id"},{"name":"agentSlug","in":"query","required":false,"schema":{"type":"string","maxLength":64}}],"responses":{"200":{"description":"Latest reports","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"reports":{"type":"array","items":{"type":"object","properties":{"runId":{"type":"string"},"agentSlug":{"type":"string"},"engine":{"type":"string","enum":["ledger","v4_pre_approval"]},"status":{"type":"string"},"done":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"reportMarkdown":{"type":"string"}}}}}}}}}}},"400":{"description":"Bad loan id or agentSlug"},"403":{"description":"API key, permission, or loan files check failed"},"404":{"description":"No loan file for this loan id, or the key owner cannot open it"}}}}}}