Otter.ai’s Public API provides programmatic access to retrieve channels, conversations, transcripts, audio, action items, insights, and outlines from your Otter account.
Authentication
All API requests require authentication using Bearer token authentication. Follow the steps below to create your API key.
- Sign in to your Otter.ai account.
- Click Integrations in the left-side navigation. Navigate to the Developer tab.
-
Click Create key.
-
Click Copy and store the API key in a safe place.
Note: This is only visible once. Make sure you copy the API key in this pop-up. If you forget to copy, follow steps 1-3 to create another key. -
The API key can now be used. Follow steps 1-4 to create another API key.
Note: There is a limit of 2 API keys per user.
Using your API key:
Include your API key in the Authorization header for every request:
Authorization: Bearer YOUR_API_KEY
✅ Security best practices:
- Never share your API key publicly or commit it to version control
- Store API keys securely using environment variables or secrets management
- Rotate API keys periodically
Rate Limits
Enterprise plan users are currently limited to 10 requests / second. If you exceed your rate limit, you'll receive a 429 Too Many Requests response.
Pagination
List endpoints use cursor-based pagination for efficient data retrieval.
Pagination Response
{
"meta": {
"retrieved_at": "2025-07-31T12:00:00Z",
"has_more": true,
"next_cursor": "next_cursor_position"
},
"data": [ /* array of results */ ]
}
Meta Fields
| Field | Type | Description |
|---|---|---|
retrieved_at |
string | Timestamp when data was retrieved (ISO 8601 format) |
has_more |
boolean | Whether more pages are available |
next_cursor |
string (optional) | Cursor for the next page |
Usage
To retrieve the next page, use the next_cursor value in your next request's cursor query parameter:
GET /conversations?cursor=next_cursor_position&limit=20
Continue paginating until has_more is false.
Webhooks
Webhooks are the recommended way to build export integrations with Otter. Instead of constantly polling the API to check for new conversations or action items, webhooks push real-time notifications to your application the moment events occur. This makes webhooks ideal for automatically syncing meeting summaries to your CRM, sending action items to project management tools, or triggering custom workflows whenever a transcript is ready. By using webhooks, you'll build more efficient integrations that respond instantly to changes while staying well within API rate limits.
Learn how to set up webhooks with our workspace webhook documentation.
Endpoints
Channels
A Channel lets you organize Conversations.
| Field | Type | Description |
|---|---|---|
id |
string | Unique channel identifier |
name |
string | Channel name |
member_count |
integer | Number of members in the channel |
owner |
User | Channel owner information |
{
"id": "channel_id",
"name": "Backend Weekly Meeting",
"member_count": 50,
"owner": {
"id": "user_id",
"name": "Jane Doe",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@test.com"
}
}
GET /channels
Returns a cursor-paginated list of channels that the authenticated user is in, ordered alphabetically by channel name.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
limit |
integer | No | Number of items per page (default: 20, min: 1, max: 100) |
cursor |
string | No | Cursor for pagination |
Example Request:
curl -X GET "<https://api.otter.ai/v1/channels?limit=20>" \\ -H "Authorization: Bearer YOUR_API_KEY"
Response: Returns a ChannelListResponse with channel data and pagination metadata.
{
"meta": {
"retrieved_at": "2025-07-31T12:00:00Z",
"has_more": true,
"next_cursor": "next_cursor_position"
},
"data": [
{
"id": "channel_id",
"name": "Backend Weekly Sync",
"member_count": 50,
"owner": {
"id": "user_id",
"name": "Jane Doe",
"first_name": "Jane",
"last_name": "Doe",
"email": "Jane@test.com"
}
}
]
}
Conversations
| Field | Type | Description |
|---|---|---|
id |
string | Unique Conversation identifier |
title |
string | Title of the Conversation |
url |
string | URL to view the Conversation on the Otter website |
owner |
User | Owner of the Otter Conversation |
created_at |
string | Timestamp the Conversation was created (ISO 8601 format) |
process_status |
object | Processing status for the AI-generated fields (abstract_summary, action_item, outline) |
calendar_guests |
array | List of calendar guests associated to the Conversation (if applicable) |
shared_emails |
array | List of email addresses with whom the Conversation is shared |
shared_channels |
array | List of Channels with which the Conversation is shared |
abstract_summary |
string | A concise AI-generated summary of the Conversation’s essential details |
conf_join_url |
string | URL of the Zoom, Google Meet, or Microsoft Teams conference (if applicable) |
POST /conversations
Creates a new conversation from a file. This is useful if you are importing calls into Otter, such as from a Dialer.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
file |
string (URL) | Yes | URL to the file to process |
name |
string | No | Name for the conversation |
Example Request:
curl -X POST "<https://api.otter.com/v1/conversations>" \\
-H "Authorization: Bearer YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{
"file": "<https://example.com/file.mp4>",
"name": "Product Launch Meeting"
}'
Response: Returns a ConversationCreateResponse with status.
{
"status": "success",
"completed_at": "2025-12-01 01:00:00Z",
"file": "audio.mp3"
}
GET /conversations
Returns a cursor-paginated list of conversations, ordered by creation time (most recent first).
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
include_shared |
boolean | No | Include conversations shared to the user (default: false) |
channel_id |
string | No | Filter conversations by channel ID (implicitly sets include_shared to true) |
limit |
integer | No | Number of items per page (default: 20, min: 1, max: 100) |
cursor |
string | No | Cursor for pagination |
Example Request:
curl -X GET "<https://api.otter.ai/v1/conversations?limit=50&include_shared=true>" \\ -H "Authorization: Bearer YOUR_API_KEY"
Response: Returns a ConversationListResponse with conversation data and pagination metadata.
{
"meta": {
"retrieved_at": "2025-10-05T12:34:56.789012Z",
"has_more": true,
"next_cursor": "cursor_id"
},
"data": [
{
"id": "conversation_id",
"title": "Team Sync – Weekly Planning",
"url": "<https://otter.ai/u/conversation_id>",
"owner": {
"id": "owner_id",
"name": "Jane Doe",
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@example.com"
},
"created_at": "2025-10-05T12:33:10Z",
"process_status": {
"abstract_summary": "completed",
"action_item": "completed",
"outline": "completed"
},
"calendar_guests": [
{
"name": "John Smith",
"email": "john.smith@example.com",
"permission": "view"
}
],
"shared_emails": [
{
"email": "guest.user@example.com",
"user": {
"id": "user_id",
"name": "Guest User",
"first_name": "Guest",
"last_name": "User",
"email": "guest.user@example.com"
},
"permission": "collaborate"
}
],
"shared_channels": [
{
"channel": {
"id": "channel_id",
"name": "Project Alpha",
"member_count": 12,
"owner": {
"id": "owner_id",
"name": "Alex Johnson",
"first_name": "Alex",
"last_name": "Johnson",
"email": "alex.johnson@example.com"
}
},
"permission": "view"
}
],
"abstract_summary": "This is the summary.",
"conf_join_url": "<https://zoom.us/j/00000000000>"
}
]
}
GET /conversations/{id}
Returns the summary and details of a specific conversation, optionally including additional data - action items, insights, outline, transcript, or all.
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
include |
string | Yes | Comma-separated list of additional data to include. |
Options: action_items, insights, outlines, transcript, all. If all is specified, every field will be returned. Example: insights,transcript |
Example Request:
curl -X GET "<https://api.otter.ai/v1/conversations/conversation_id?include=insights,transcript>" \\ -H "Authorization: Bearer YOUR_API_KEY"
-
Response: Returns a
ConversationResponsewith conversation details and requested relationships.{ "meta": { "retrieved_at": "2025-10-05T12:00:00Z" }, "data": { "id": "conversation_id", "title": "Customer Discovery Call – ACME Corp", "url": "<https://otter.ai/u/conversation_id>", "owner": { "id": "owner_id", "name": "Jane Doe", "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.com" }, "created_at": "2025-10-05T11:55:00Z", "process_status": { "abstract_summary": "finished", "action_item": "finished", "outline": "finished" }, "calendar_guests": null, "shared_emails": [], "shared_channels": [ { "channel": { "id": "channel_id", "name": "All customer calls", "member_count": 25, "owner": { "id": "channel_owner_id", "name": "John Smith", "first_name": "John", "last_name": "Smith", "email": "john.smith@example.com" } }, "permission": "collaborate" } ], "abstract_summary": "The team met with ACME Corp to confirm their requirements, discuss pricing options, and align on an evaluation timeline for adopting Otter.ai across their go-to-market team.", "conf_join_url": "<https://zoom.us/j/00000000000>", "relationships": { "insights": [ { "topic": "Budget", "text": [ "ACME has a preliminary budget in place and is comfortable with a per-seat model as long as usage is clear.", "They are open to a flat-rate option if it simplifies internal approvals." ] }, { "topic": "Authority", "text": [ "Alex Taylor is the main champion, but final approval will come from the VP of Operations.", "Security and procurement teams will review the proposal before signature." ] }, { "topic": "Need", "text": [ "ACME needs automated call summaries for customer meetings and better visibility into team activity.", "They want to reduce manual note-taking and ensure consistent follow-up on action items." ] }, { "topic": "Timeline", "text": [ "They aim to complete evaluation this month and go live at the start of next quarter.", "Next internal decision checkpoint is scheduled for next week." ] } ], "transcript": { "content": "Jane Doe 00:00\\nThanks everyone for joining today. I’d love to understand how your team handles customer calls and where Otter might help.\\n\\nAlex Taylor 00:07\\nRight now we take notes manually, and we often miss details or lose track of follow-ups after the meeting.\\n\\nJane Doe 00:14\\nThat makes sense. Otter can automatically capture the conversation, generate summaries, and highlight key action items.\\n\\nAlex Taylor 00:21\\nThat would be really valuable for us, especially for onboarding new reps and improving consistency.\\n\\nJane Doe 00:28\\nGreat—I'll send a follow-up with pricing options and a proposed rollout timeline.\\n\\nAlex Taylor 00:35\\nSounds good. We'll review internally and get back to you this week.", "format": "txt" } } } }
Example Request:
curl -X GET "<https://api.otter.ai/v1/conversations/conversation_id?include=all>" \\ -H "Authorization: Bearer YOUR_API_KEY"
-
Response: Returns a
ConversationResponsewith conversation details and requested relationships.{ "meta": { "retrieved_at": "2025-10-05T12:00:00Z" }, "data": { "id": "conversation_id", "title": "Customer Discovery Call – ACME Corp", "url": "<https://otter.ai/u/conversation_id>", "owner": { "id": "owner_id", "name": "Jane Doe", "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.com" }, "created_at": "2025-10-05T11:55:00Z", "process_status": { "abstract_summary": "finished", "action_item": "finished", "outline": "finished" }, "calendar_guests": null, "shared_emails": [], "shared_channels": [ { "channel": { "id": "channel_id", "name": "All customer calls", "member_count": 25, "owner": { "id": "channel_owner_id", "name": "John Smith", "first_name": "John", "last_name": "Smith", "email": "john.smith@example.com" } }, "permission": "collaborate" } ], "abstract_summary": "The team met with ACME Corp to confirm their requirements, discuss pricing options, and align on an evaluation timeline for adopting Otter.ai across their go-to-market team.", "conf_join_url": "<https://zoom.us/j/00000000000>", "relationships": { "action_items": [ { "id": "action_item_id_1", "text": "Send follow-up email with pricing summary and implementation overview.", "assignee": { "id": "owner_id", "name": "Jane Doe", "first_name": "Jane", "last_name": "Doe", "email": "jane.doe@example.com" }, "status": null }, { "id": "action_item_id_2", "text": "ACME to confirm final user count and preferred contract term.", "assignee": { "id": "customer_contact_id", "name": "Alex Taylor", "first_name": "Alex", "last_name": "Taylor", "email": "alex.taylor@example.com" }, "status": null } ], "insights": [ { "topic": "Budget", "text": [ "ACME has a preliminary budget in place and is comfortable with a per-seat model as long as usage is clear.", "They are open to a flat-rate option if it simplifies internal approvals." ] }, { "topic": "Authority", "text": [ "Alex Taylor is the main champion, but final approval will come from the VP of Operations.", "Security and procurement teams will review the proposal before signature." ] }, { "topic": "Need", "text": [ "ACME needs automated call summaries for customer meetings and better visibility into team activity.", "They want to reduce manual note-taking and ensure consistent follow-up on action items." ] }, { "topic": "Timeline", "text": [ "They aim to complete evaluation this month and go live at the start of next quarter.", "Next internal decision checkpoint is scheduled for next week." ] } ], "outlines": [ { "section": "Introductions and Context", "text": [ "Participants introduced themselves and clarified roles.", "ACME shared context on their current workflow and challenges with manual note-taking." ] }, { "section": "Pricing and Rollout Options", "text": [ "The team reviewed per-seat and flat-rate pricing options.", "They discussed rollout plans starting with key go-to-market teams and expanding later." ] } ], "transcript": { "content": "Jane Doe 00:00\\nThanks everyone for joining today. I’d love to understand how your team handles customer calls and where Otter might help.\\n\\nAlex Taylor 00:07\\nRight now we take notes manually, and we often miss details or lose track of follow-ups after the meeting.\\n\\nJane Doe 00:14\\nThat makes sense. Otter can automatically capture the conversation, generate summaries, and highlight key action items.\\n\\nAlex Taylor 00:21\\nThat would be really valuable for us, especially for onboarding new reps and improving consistency.\\n\\nJane Doe 00:28\\nGreat—I'll send a follow-up with pricing options and a proposed rollout timeline.\\n\\nAlex Taylor 00:35\\nSounds good. We'll review internally and get back to you this week.", "format": "txt" }, "custom_prompt": null } } }
👉 Best Practices
Rate Limiting
Implement appropriate rate limiting in your application to avoid overwhelming the API. Consider implementing exponential backoff for retries.
Error Handling
Always check for and handle error responses gracefully. Parse the error details to provide meaningful feedback to users.
Pagination
Use cursor-based pagination for large result sets. Don't attempt to retrieve all data in a single request.
Selective Loading
Use the include parameter in conversation endpoints to fetch only the data you need. This reduces response payload size and improves performance.
Caching
Cache responses where appropriate to reduce API calls. Consider implementing a caching layer for frequently accessed data.
Field Selection
When using the include parameter, only request the fields you actually need rather than using all
Feedback
0 comments
Article is closed for comments.