EDMO Agent Builder API
version: “1.0.0”
description: The Edmo Agent Builder API lets you manage AI voice/chat agents, tools, phone
numbers and call analytics used by the Edmo platform.
It is designed so that:
- **Non-technical stakeholders** can read the summaries and examples to understand
what the system does.
- **Developers** can rely on the schemas and status codes to integrate with the
backend services.
All endpoints in this spec are served from the `/api` prefix of the main Edmo
web application (see the `servers` section below).
servers:
- url: https://agents.goedmo.com/api
description: Production Edmo deployment - url: http://localhost:3000/api
description: Local development
tags:
- name: Auth
description: Authentication and current-user endpoints. - name: Assistants
description: Manage AI agents (assistants) used for calls and chat. - name: Tools
description: Manage integrations and tools that assistants can call. - name: Phone Numbers
description: Manage phone numbers that can be attached to assistants. - name: Analytics
description: Read-only analytics and conversation insights. - name: Chat
description: Simple text chat interface to an assistant.
x-tagGroups:
- name: Authentication tags:
- Auth
- name: Assistants tags:
- Assistants
- name: Tools tags:
- Tools
- name: Phone Numbers tags:
- Phone Numbers
- name: Analytics tags:
- Analytics
- name: Chat tags:
- Chat
components:
securitySchemes:
CookieAuth:
type: apiKey
in: cookie
name: auth-token
description: |
Authentication is handled via an auth-token HTTP-only cookie set by the/auth/login endpoint.
- In a **browser**, you typically call `/auth/login` once and the cookie will
be stored and automatically sent on subsequent API requests.
- In **API tools** (Postman, curl, etc.) you can manually capture the cookie
from the `Set-Cookie` header or configure cookie handling.
This spec models the cookie using `apiKey`-style auth for documentation
purposes.
AnalyticsApiKey:
type: apiKey
in: header
name: X-API-Key
description: |
API key used to access the public analytics endpoints.
The value must match the `ANALYTICS_API_KEY` environment variable
configured on the server. This is intended for external analytics
dashboards and reporting tools, not for the main Edmo dashboard UI.
schemas:
# —————————-
# Generic / shared structures
# —————————-
ErrorResponse:
type: object
description: Standard error response envelope.
properties:
error:
type: string
description: Human-readable error message.
required:
– error
example:
error: Failed to load agents. Please try again.
PaginationMeta:
type: object
description: Optional paging metadata returned by some list endpoints.
properties:
total:
type: integer
example: 125
limit:
type: integer
example: 50
offset:
type: integer
example: 0
# ----------------------------
# Auth & user-related schemas
# ----------------------------
LoginRequest:
type: object
description: Credentials used to sign into the Edmo dashboard and API.
properties:
email:
type: string
format: email
example: user@example.edu
password:
type: string
format: password
example: "strong-password-123"
required:
- email
- password
LoginResponse:
type: object
description: Successful login response. The auth cookie is sent via `Set-Cookie` header.
properties:
message:
type: string
example: Login successful
user:
$ref: "#/components/schemas/User"
required:
- message
- user
User:
type: object
description: Basic user information for the currently authenticated user.
properties:
id:
type: string
description: Internal user identifier.
email:
type: string
format: email
name:
type: string
nullable: true
role:
type: string
description: High-level role for permissions (e.g., ADMIN, EDITOR, VIEWER).
disabled:
type: boolean
description: Whether the account is disabled.
permissions:
type: object
nullable: true
additionalProperties:
type: array
items:
type: string
description: Fine-grained permission map used internally.
required:
- id
- email
- role
- disabled
CurrentUserResponse:
type: object
description: Envelope used by `/auth/me` to return the current user.
properties:
user:
$ref: "#/components/schemas/User"
required:
- user
# ----------------------------
# Assistant-related schemas
# ----------------------------
ModelConfig:
type: object
description: |
Configuration for the underlying language model (OpenAI / Anthropic).
For non-technical readers, you can think of this as picking which "brain"
the agent uses and how creative it should be.
properties:
provider:
type: string
enum:
- openai
- anthropic
model:
type: string
description: Model name from the chosen provider.
example: gpt-4o
temperature:
type: number
description: |
Controls creativity. Lower values are more deterministic, higher values
more creative and varied.
minimum: 0
maximum: 2
example: 0.7
maxTokens:
type: integer
description: Maximum number of tokens the model can generate for a response.
example: 1024
required:
- provider
- model
VoiceConfig:
type: object
description: Voice configuration for spoken responses when used in calls.
properties:
provider:
type: string
description: Voice provider identifier.
enum:
- 11labs
- azure
- cartesia
- deepgram
- playht
- openai
- edmo
voiceId:
type: string
description: Voice identifier within the chosen provider.
example: alloy
TranscriberConfig:
type: object
description: Speech-to-text configuration used to transcribe calls.
properties:
provider:
type: string
enum:
- deepgram
- assemblyai
- whisper
model:
type: string
nullable: true
description: Optional model identifier, depending on the provider.
Assistant:
type: object
description: |
A voice/chat agent configuration that defines how the assistant behaves and
which model, voice and tools it uses.
properties:
id:
type: string
description: Assistant identifier.
orgId:
type: string
description: Owning organization identifier.
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
name:
type: string
nullable: true
description: Human-friendly assistant name shown in the dashboard.
firstMessage:
type: string
nullable: true
description: First message sent by the assistant when a call/chat starts.
firstMessageMode:
type: string
nullable: true
enum:
- assistant-speaks-first
- assistant-waits-for-user
- assistant-speaks-first-with-model-generated-message
model:
$ref: "#/components/schemas/ModelConfig"
voice:
$ref: "#/components/schemas/VoiceConfig"
transcriber:
$ref: "#/components/schemas/TranscriberConfig"
voicemailMessage:
type: string
nullable: true
endCallMessage:
type: string
nullable: true
endCallPhrases:
type: array
items:
type: string
nullable: true
metadata:
type: object
nullable: true
additionalProperties: true
maxDurationSeconds:
type: integer
nullable: true
required:
- id
- orgId
- createdAt
- updatedAt
- model
- voice
example:
id: asst_123
orgId: org_abc
createdAt: "2024-01-01T10:00:00.000Z"
updatedAt: "2024-01-02T12:00:00.000Z"
name: Enrollment Assistant
firstMessage: "Hi, I'm here to help with your enrollment questions."
firstMessageMode: assistant-speaks-first
model:
provider: openai
model: gpt-4o
temperature: 0.7
voice:
provider: openai
voiceId: alloy
maxDurationSeconds: 1800
CreateAssistantRequest:
type: object
description: Payload used to create a new assistant.
properties:
name:
type: string
description: Assistant display name.
firstMessage:
type: string
nullable: true
firstMessageMode:
type: string
nullable: true
enum:
- assistant-speaks-first
- assistant-waits-for-user
- assistant-speaks-first-with-model-generated-message
model:
$ref: "#/components/schemas/ModelConfig"
voice:
$ref: "#/components/schemas/VoiceConfig"
transcriber:
$ref: "#/components/schemas/TranscriberConfig"
voicemailMessage:
type: string
nullable: true
endCallMessage:
type: string
nullable: true
endCallPhrases:
type: array
items:
type: string
nullable: true
metadata:
type: object
nullable: true
additionalProperties: true
maxDurationSeconds:
type: integer
nullable: true
required:
- model
- voice
example:
name: Enrollment Assistant
firstMessage: "Hi, I'm your enrollment assistant. How can I help today?"
firstMessageMode: assistant-speaks-first
model:
provider: openai
model: gpt-4o
temperature: 0.6
voice:
provider: openai
voiceId: alloy
maxDurationSeconds: 1800
UpdateAssistantRequest:
allOf:
- $ref: "#/components/schemas/CreateAssistantRequest"
description: Partial update payload for an existing assistant. All fields are optional.
# ----------------------------
# Tool-related schemas
# ----------------------------
ToolMessage:
type: object
description: |
Optional user-facing status messages spoken or displayed while a tool runs.
properties:
type:
type: string
enum:
- request-start
- request-complete
- request-failed
- request-response-delayed
content:
type: string
description: Message text.
required:
- type
- content
ToolParameter:
type: object
description: JSON Schema-style description of a single input field.
properties:
type:
type: string
enum:
- string
- number
- boolean
- object
- array
description:
type: string
enum:
type: array
items:
type: string
items:
$ref: "#/components/schemas/ToolParameter"
properties:
type: object
additionalProperties:
$ref: "#/components/schemas/ToolParameter"
required:
- type
BaseTool:
type: object
description: Common metadata shared by all tool types.
properties:
id:
type: string
orgId:
type: string
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
type:
type: string
enum:
- function
- apiRequest
- mcp
async:
type: boolean
nullable: true
messages:
type: array
items:
$ref: "#/components/schemas/ToolMessage"
nullable: true
FunctionTool:
allOf:
- $ref: "#/components/schemas/BaseTool"
- type: object
properties:
type:
type: string
enum:
- function
function:
type: object
properties:
name:
type: string
description:
type: string
parameters:
type: object
properties:
type:
type: string
enum:
- object
properties:
type: object
additionalProperties:
$ref: "#/components/schemas/ToolParameter"
required:
type: array
items:
type: string
required:
- name
- description
- parameters
server:
type: object
nullable: true
properties:
url:
type: string
format: uri
secret:
type: string
nullable: true
timeoutSeconds:
type: integer
nullable: true
ApiRequestTool:
allOf:
- $ref: "#/components/schemas/BaseTool"
- type: object
properties:
type:
type: string
enum:
- apiRequest
name:
type: string
description:
type: string
nullable: true
method:
type: string
enum:
- GET
- POST
- PUT
- PATCH
- DELETE
url:
type: string
timeoutSeconds:
type: integer
nullable: true
McpTool:
allOf:
- $ref: "#/components/schemas/BaseTool"
- type: object
properties:
type:
type: string
enum:
- mcp
name:
type: string
nullable: true
metadata:
type: object
nullable: true
server:
type: object
properties:
url:
type: string
format: uri
required:
- url
Tool:
oneOf:
- $ref: "#/components/schemas/FunctionTool"
- $ref: "#/components/schemas/ApiRequestTool"
- $ref: "#/components/schemas/McpTool"
discriminator:
propertyName: type
description: Union type covering all supported tool configurations.
ToolWithProvider:
allOf:
- $ref: "#/components/schemas/Tool"
- type: object
properties:
provider:
type: string
nullable: true
description: Optional source/provider of the tool (e.g., "salesforce", "workday").
CreateToolRequest:
type: object
description: Payload used to create a new tool.
properties:
provider:
type: string
nullable: true
description: Optional logical provider label for grouping tools (stored locally).
type:
type: string
enum:
- function
- apiRequest
- mcp
# Remaining properties mirror the underlying tool request bodies.
required:
- type
example:
provider: salesforce
type: apiRequest
# ----------------------------
# Phone number schemas
# ----------------------------
PhoneNumber:
type: object
description: A phone number managed by the Edmo platform, optionally attached to an assistant.
properties:
id:
type: string
provider:
type: string
description: Source of the number (edmo, twilio, vonage, etc.).
number:
type: string
description: E.164 formatted phone number.
example: "+17865550123"
assistantId:
type: string
nullable: true
required:
- id
- provider
- number
CreatePhoneNumberRequest:
type: object
description: |
Request to create or import a phone number from a provider.
This payload is flexible and mirrors the app's conditional logic for
different telephony providers.
properties:
provider:
type: string
enum:
- edmo
- twilio
- vonage
assistantId:
type: string
nullable: true
numberDesiredAreaCode:
type: string
description: Used for Edmo-provided numbers.
example: "786"
twilioPhoneNumber:
type: string
description: Existing Twilio number to import.
twilioAccountSid:
type: string
twilioAuthToken:
type: string
vonageApiKey:
type: string
vonageApiSecret:
type: string
vonagePhoneNumber:
type: string
required:
- provider
example:
provider: edmo
numberDesiredAreaCode: "786"
assistantId: asst_123
# ----------------------------
# Analytics schemas
# ----------------------------
AnalyticsConversationCustomer:
type: object
description: Basic customer information for an analytics conversation.
properties:
number:
type: string
nullable: true
description: Customer phone number if available.
AnalyticsConversationAnalysis:
type: object
description: High-level analysis for a conversation.
properties:
summary:
type: string
nullable: true
description: Short natural-language summary of the conversation.
successEvaluation:
type: string
nullable: true
description: Whether the conversation was considered successful (`\"true\"` or `\"false\"`).
AnalyticsConversation:
type: object
description: Analytics view of a single conversation/call.
properties:
id:
type: string
description: Conversation/call identifier.
timestamp:
type: string
format: date-time
description: When the conversation record was created.
timestampFormatted:
type: string
nullable: true
description: Human-friendly formatted timestamp.
type:
type: string
description: Internal call type (e.g., webCall, inboundPhoneCall, outboundPhoneCall).
channel:
type: string
enum:
- web
- phone
description: High-level channel for the conversation.
status:
type: string
description: Current status of the call (e.g., completed).
endedReason:
type: string
nullable: true
description: Reason the call ended (assistant-ended-call, customer-ended-call, etc.).
durationSeconds:
type: integer
description: Total duration of the conversation in seconds.
durationFormatted:
type: string
description: Human-readable duration (for example, "3m 20s").
sentiment:
type: string
enum:
- positive
- neutral
- negative
description: Overall sentiment classification.
resolution:
type: string
enum:
- resolved
- escalated
- failed
description: High-level outcome classification.
assistantId:
type: string
nullable: true
description: Assistant associated with this conversation, if any.
phoneNumberId:
type: string
nullable: true
description: Phone number associated with this conversation, if any.
customer:
$ref: "#/components/schemas/AnalyticsConversationCustomer"
analysis:
$ref: "#/components/schemas/AnalyticsConversationAnalysis"
AnalyticsMeta:
type: object
description: Metadata describing the analytics query that produced the results.
properties:
timeRangeDays:
type: integer
enum:
- 7
- 30
- 90
description: Number of days included in the analytics window.
channel:
type: string
enum:
- all
- web
- phone
description: Channel filter applied to the analytics query.
sentiment:
type: string
enum:
- all
- positive
- neutral
- negative
description: Sentiment filter applied to the analytics query.
resolution:
type: string
enum:
- all
- resolved
- escalated
- failed
description: Resolution filter applied to the analytics query.
assistantId:
type: string
nullable: true
description: Assistant filter applied, if any.
phoneNumberId:
type: string
nullable: true
description: Phone number filter applied, if any.
totalConversationsReturned:
type: integer
description: Number of conversations returned after filtering.
AnalyticsSummaryByChannel:
type: object
description: Conversation counts broken down by channel.
properties:
web:
type: integer
description: Number of web conversations.
phone:
type: integer
description: Number of phone conversations.
AnalyticsSummaryKnowledgeGaps:
type: object
description: Knowledge gap statistics derived from the knowledge base.
properties:
totalGaps:
type: integer
description: Total number of pending knowledge gaps.
highPriorityGaps:
type: integer
description: Number of high-priority pending knowledge gaps.
AnalyticsSummary:
type: object
description: Aggregated summary metrics for the analytics query.
properties:
totalConversations:
type: integer
description: Total number of conversations in the period.
successfulConversations:
type: integer
description: Number of conversations considered resolved.
failedConversations:
type: integer
description: Number of conversations that failed.
successRatePercent:
type: integer
description: Percentage of conversations that were successful.
totalDurationSeconds:
type: integer
description: Total duration of all conversations in seconds.
avgDurationSeconds:
type: integer
description: Average duration per conversation in seconds.
escalatedConversations:
type: integer
description: Number of escalated conversations.
escalationRatePercent:
type: integer
description: Percentage of conversations that were escalated.
timeSavedHours:
type: integer
description: Estimated hours saved compared to human-handled calls.
byChannel:
$ref: "#/components/schemas/AnalyticsSummaryByChannel"
knowledgeGaps:
$ref: "#/components/schemas/AnalyticsSummaryKnowledgeGaps"
AnalyticsResponse:
type: object
description: Response envelope for the analytics overview endpoint.
properties:
meta:
$ref: "#/components/schemas/AnalyticsMeta"
summary:
$ref: "#/components/schemas/AnalyticsSummary"
conversations:
type: array
items:
$ref: "#/components/schemas/AnalyticsConversation"
ConversationDetailMessage:
type: object
description: Single message within a conversation transcript.
properties:
role:
type: string
enum:
- user
- assistant
description: Who sent the message.
message:
type: string
description: Message text content.
ConversationDetailResponse:
type: object
description: Full details for a single conversation.
properties:
id:
type: string
description: Conversation/call identifier.
type:
type: string
description: Internal call type (e.g., webCall, inboundPhoneCall, outboundPhoneCall).
channel:
type: string
enum:
- web
- phone
description: High-level channel for the conversation.
status:
type: string
description: Current status of the call.
endedReason:
type: string
nullable: true
description: Reason the call ended.
startedAt:
type: string
format: date-time
nullable: true
endedAt:
type: string
format: date-time
nullable: true
createdAt:
type: string
format: date-time
durationSeconds:
type: integer
description: Total duration of the conversation in seconds.
durationFormatted:
type: string
description: Human-readable duration (for example, "3m 20s").
sentiment:
type: string
enum:
- positive
- neutral
- negative
resolution:
type: string
enum:
- resolved
- escalated
- failed
customer:
type: object
description: Customer information.
properties:
number:
type: string
nullable: true
assistant:
type: object
description: Assistant information.
properties:
id:
type: string
nullable: true
analysis:
$ref: "#/components/schemas/AnalyticsConversationAnalysis"
transcript:
type: string
nullable: true
description: Raw transcript text, if available.
messages:
type: array
description: Parsed or structured messages making up the transcript.
items:
$ref: "#/components/schemas/ConversationDetailMessage"
recordingUrl:
type: string
nullable: true
description: URL of the mixed-call recording, if available.
stereoRecordingUrl:
type: string
nullable: true
description: URL of the stereo recording, if available.
# ----------------------------
# Chat schemas
# ----------------------------
ChatRequest:
type: object
description: Send a single message to an assistant over text chat.
properties:
assistantId:
type: string
description: Target assistant identifier.
message:
type: string
description: End-user message text.
previousChatId:
type: string
nullable: true
description: Optional prior chat ID to maintain context across turns.
required:
- assistantId
- message
example:
assistantId: asst_123
message: "I have a question about my application status."
ChatResponse:
type: object
description: Assistant reply and chat metadata.
properties:
message:
type: string
description: Assistant's reply text.
chatId:
type: string
description: Chat identifier to send as `previousChatId` on the next turn.
cost:
type: number
nullable: true
description: Optional cost information returned by the underlying provider.
timestamp:
type: string
format: date-time
required:
- message
- chatId
- timestamp
paths:
# ============================
# Auth
# ============================
/auth/login:
post:
tags:
– Auth
summary: Log in and obtain an auth cookie
description: |
Authenticates a user with email and password.
- On success, returns basic user information and sets an `auth-token`
HTTP-only cookie used to authorize subsequent requests.
- On failure, returns an error message and **does not** set the cookie.
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/LoginRequest"
examples:
default:
value:
email: admin@example.edu
password: "strong-password-123"
responses:
"200":
description: Login successful. Auth cookie is set in the response.
headers:
Set-Cookie:
description: Contains the `auth-token` cookie for subsequent requests.
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/LoginResponse"
"400":
description: Missing email or password.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Invalid credentials or account not found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: Account is disabled.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Unexpected server error during login.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/auth/me:
get:
tags:
– Auth
summary: Get the currently authenticated user
description: |
Returns information about the currently logged-in user.
This endpoint is useful for front-end apps to confirm who is signed in and
what permissions they have. It relies on the `auth-token` cookie set by
`/auth/login`.
security:
- CookieAuth: [ ]
responses:
"200":
description: Authenticated user details.
content:
application/json:
schema:
$ref: "#/components/schemas/CurrentUserResponse"
"401":
description: No valid auth cookie was provided.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: The user referenced by the token no longer exists.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: The user account is disabled.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Unexpected server error.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
# ============================
# Assistants
# ============================
/assistants:
get:
tags:
– Assistants
summary: List assistants
description: |
Returns all assistants stored in the local database using the standard
assistant representation.
Use this to populate dashboards or configuration UIs that show available
agents.
security:
- CookieAuth: [ ]
responses:
"200":
description: List of assistants.
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Assistant"
"401":
description: Not authenticated or lacking permission to read agents.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error listing assistants.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
post:
tags:
- Assistants
summary: Create a new assistant
description: |
Creates a new assistant in the Edmo platform and persists a copy to
the local database.
Typical flow:
1. Your app sends a configuration payload.
2. Edmo provisions the assistant with the underlying AI/voice providers.
3. Edmo stores the assistant locally for display and future management.
security:
- CookieAuth: [ ]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateAssistantRequest"
responses:
"201":
description: Assistant created successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/Assistant"
"401":
description: Not authenticated or lacking permission to create agents.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Creation failed due to configuration or provider issues.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/assistants/{id}:
get:
tags:
– Assistants
summary: Get a specific assistant
description: |
Fetches a single assistant from the local database by either its external
provider ID or internal database ID.
security:
– CookieAuth: [ ]
parameters:
– name: id
in: path
required: true
description: Assistant identifier (external provider ID or local DB ID).
schema:
type: string
responses:
“200”:
description: Assistant details.
content:
application/json:
schema:
$ref: “#/components/schemas/Assistant”
“404”:
description: Assistant not found.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
“401”:
description: Not authenticated or lacking permission to read agents.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
“500”:
description: Error fetching assistant.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
patch:
tags:
- Assistants
summary: Update an assistant
description: |
Updates an existing assistant in both the external provider and the local
database using a partial configuration payload.
security:
- CookieAuth: [ ]
parameters:
- name: id
in: path
required: true
schema:
type: string
description: Assistant identifier (external provider ID or local DB ID).
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/UpdateAssistantRequest"
responses:
"200":
description: Assistant updated successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/Assistant"
"404":
description: Assistant not found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Not authenticated or lacking permission to update agents.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error updating assistant or communicating with the external provider.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
delete:
tags:
- Assistants
summary: Delete an assistant
description: |
Deletes an assistant from both the external provider and the local database.
Use this when an agent is no longer needed.
security:
- CookieAuth: [ ]
parameters:
- name: id
in: path
required: true
schema:
type: string
description: Assistant identifier (external provider ID or local DB ID).
responses:
"200":
description: Assistant deleted successfully.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
"404":
description: Assistant not found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Not authenticated or lacking permission to delete agents.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error deleting assistant or communicating with the external provider.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
# ============================
# Tools
# ============================
/tools:
get:
tags:
– Tools
summary: List tools
description: |
Returns all tools stored in the local database, converted into the
standard tool format and annotated with an optional provider field.
Tools represent external integrations or custom functions that assistants
can call (for example, CRM lookups or internal APIs).
security:
- CookieAuth: [ ]
responses:
"200":
description: List of tools.
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/ToolWithProvider"
"401":
description: Not authenticated or lacking permission to read integrations.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error listing tools.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
post:
tags:
- Tools
summary: Create a new tool
description: |
Creates a new tool in the Edmo platform and stores it in the local
database, optionally tagging it with a logical `provider` name.
security:
- CookieAuth: [ ]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreateToolRequest"
responses:
"201":
description: Tool created successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/ToolWithProvider"
"401":
description: Not authenticated or lacking permission to create integrations.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error creating tool or communicating with the external provider.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/tools/{id}:
get:
tags:
– Tools
summary: Get a specific tool
description: |
Fetches a single tool from the local database by its external provider
ID or internal database ID.
security:
– CookieAuth: [ ]
parameters:
– name: id
in: path
required: true
schema:
type: string
description: Tool identifier (external provider ID or local DB ID).
responses:
“200”:
description: Tool details.
content:
application/json:
schema:
$ref: “#/components/schemas/ToolWithProvider”
“404”:
description: Tool not found.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
“401”:
description: Not authenticated or lacking permission to read integrations.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
“500”:
description: Error fetching tool.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
patch:
tags:
- Tools
summary: Update a tool
description: |
Updates a tool in the external provider and the local database. The incoming payload may
include a `provider` field which is stored only locally.
security:
- CookieAuth: [ ]
parameters:
- name: id
in: path
required: true
schema:
type: string
description: Tool identifier (external provider ID or local DB ID).
requestBody:
required: true
content:
application/json:
schema:
type: object
description: Partial tool configuration matching the underlying tool API.
responses:
"200":
description: Tool updated successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/ToolWithProvider"
"404":
description: Tool not found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Not authenticated or lacking permission to update integrations.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error updating tool or communicating with the external provider.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
delete:
tags:
- Tools
summary: Delete a tool
description: |
Deletes a tool from the external provider and removes its record from the local database.
security:
- CookieAuth: [ ]
parameters:
- name: id
in: path
required: true
schema:
type: string
description: Tool identifier (external provider ID or local DB ID).
responses:
"200":
description: Tool deleted successfully.
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
"404":
description: Tool not found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Not authenticated or lacking permission to delete integrations.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error deleting tool or communicating with the external provider.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
# ============================
# Phone numbers
# ============================
/phone-numbers:
get:
tags:
– Phone Numbers
summary: List phone numbers
description: |
Returns all phone numbers available via the telephony provider APIs. These
numbers may be Edmo-provided or imported from external providers like
Twilio or Vonage.
security:
– CookieAuth: [ ]
responses:
“200”:
description: List of phone numbers.
content:
application/json:
schema:
type: array
items:
$ref: “#/components/schemas/PhoneNumber”
“401”:
description: Not authenticated or lacking permission to read phone numbers.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
“500”:
description: Error fetching phone numbers or communicating with telephony providers.
content:
application/json:
schema:
$ref: “#/components/schemas/ErrorResponse”
post:
tags:
- Phone Numbers
summary: Create or import a phone number
description: |
Creates or imports a phone number from Edmo, Twilio or Vonage and optionally
assigns it to an assistant.
The exact fields required depend on the selected `provider`:
- `edmo`: Edmo-provided number, requires `numberDesiredAreaCode`.
- `twilio`: imports an existing Twilio number.
- `vonage`: attaches a number using Vonage credentials.
security:
- CookieAuth: [ ]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/CreatePhoneNumberRequest"
responses:
"201":
description: Phone number created or imported successfully.
content:
application/json:
schema:
$ref: "#/components/schemas/PhoneNumber"
"401":
description: Not authenticated or lacking permission to manage phone numbers.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error creating phone number or invalid credentials for the selected provider.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
# ============================
# Analytics
# ============================
/analytics:
get:
tags:
– Analytics
summary: Get analytics overview
description: |
Provides analytics data for recent conversations with flexible filtering options.
This endpoint is typically used by external dashboards to show conversation
volumes, success rates, channel mix, and knowledge-gap statistics.
security:
- AnalyticsApiKey: [ ]
parameters:
- name: timeRangeDays
in: query
required: false
description: Number of days to include in the analytics window.
schema:
type: integer
enum:
- 7
- 30
- 90
default: 7
- name: channel
in: query
required: false
description: Filter conversations by channel.
schema:
type: string
enum:
- all
- web
- phone
default: all
- name: sentiment
in: query
required: false
description: Filter conversations by overall sentiment.
schema:
type: string
enum:
- all
- positive
- neutral
- negative
default: all
- name: resolution
in: query
required: false
description: Filter conversations by high-level outcome.
schema:
type: string
enum:
- all
- resolved
- escalated
- failed
default: all
- name: assistantId
in: query
required: false
description: Filter conversations by assistant identifier.
schema:
type: string
- name: phoneNumberId
in: query
required: false
description: Filter conversations by phone number identifier.
schema:
type: string
responses:
"200":
description: Analytics overview data.
content:
application/json:
schema:
$ref: "#/components/schemas/AnalyticsResponse"
"401":
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: API key is not permitted to access analytics.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error fetching analytics data.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
/analytics/{conversationId}:
get:
tags:
– Analytics
summary: Get conversation details
description: |
Returns full details for a single conversation, including basic metadata,
analysis, transcript, messages, and recording URLs.
Use this endpoint when a user drills into a specific conversation in an
analytics dashboard.
security:
- AnalyticsApiKey: [ ]
parameters:
- name: conversationId
in: path
required: true
description: Conversation or call identifier.
schema:
type: string
responses:
"200":
description: Conversation details.
content:
application/json:
schema:
$ref: "#/components/schemas/ConversationDetailResponse"
"400":
description: Invalid or missing conversationId.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Missing or invalid API key.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"403":
description: API key is not permitted to access analytics.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"404":
description: Conversation not found.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error fetching conversation details.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
# ============================
# Chat
# ============================
/chat:
post:
tags:
– Chat
summary: Send a chat message to an assistant
description: |
Sends a single text message to the specified assistant using a chat API
and returns the assistant’s reply.
For multi-turn conversations:
1. Call this endpoint and store the returned `chatId`.
2. Include that `chatId` as `previousChatId` in the next request.
security:
- CookieAuth: [ ]
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/ChatRequest"
responses:
"200":
description: Assistant reply message.
content:
application/json:
schema:
$ref: "#/components/schemas/ChatResponse"
"400":
description: Missing assistant ID or message.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"401":
description: Not authenticated or lacking permission to use agents.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"
"500":
description: Error calling the underlying chat API.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorResponse"