Endpoints
GET
Retrieve conversations
GET Single
Get one conversation
POST
Create from text
PATCH
Update conversation
DELETE
Delete conversation
POST Segments
Create from transcript
Get Conversations
GET /v1/dev/user/conversations
Retrieve your conversation transcripts (only completed, non-discarded)
Query Parameters
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Maximum number to return |
offset | integer | 0 | Number to skip |
start_date | datetime | - | Filter by start date (inclusive) |
end_date | datetime | - | Filter by end date (inclusive) |
include_transcript | boolean | false | Include full transcript segments |
categories | string | - | Comma-separated list of categories to filter by (e.g. work,personal). Matches conversations whose category is any of the listed values (OR semantics). |
folder_id | string | - | Filter by folder ID. Each conversation belongs to at most one folder, so this is a single-value filter. Must be a non-empty string if provided. Use GET /v1/dev/user/folders to retrieve folder IDs. |
starred | boolean | - | Filter by starred status. true for starred only, false for non-starred only. Omit to return all. |
- cURL
- Python
- JavaScript
curl -H "Authorization: Bearer $API_KEY" \
"https://api.omi.me/v1/dev/user/conversations?limit=10&include_transcript=true"
import requests
response = requests.get(
"https://api.omi.me/v1/dev/user/conversations",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"limit": 10, "include_transcript": True}
)
conversations = response.json()
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations?limit=10&include_transcript=true",
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const conversations = await response.json();
Response (without transcript)
Response (without transcript)
[
{
"id": "conv_202",
"created_at": "2025-01-20T13:50:00Z",
"started_at": "2025-01-20T13:50:00Z",
"finished_at": "2025-01-20T14:10:00Z",
"language": "en",
"source": "omi",
"structured": {
"title": "Feature Discussion",
"overview": "Brainstorming session for new features",
"emoji": "💼",
"category": "business",
"action_items": [
{
"description": "Create mockups for new UI",
"completed": false,
"created_at": "2025-01-20T14:10:00Z",
"updated_at": "2025-01-20T14:10:00Z",
"due_at": null,
"completed_at": null
}
],
"events": []
},
"folder_id": "folder_uuid",
"folder_name": "Work",
"geolocation": {
"latitude": 37.7749295,
"longitude": -122.4194155,
"address": "1 Market St, San Francisco, CA 94105, USA",
"google_place_id": "ChIJIQBpAG2ahYAR_6128GcTUEo",
"location_type": "street_address"
}
}
]
Response (with transcript)
Response (with transcript)
[
{
"id": "conv_202",
"created_at": "2025-01-20T13:50:00Z",
"started_at": "2025-01-20T13:50:00Z",
"finished_at": "2025-01-20T14:10:00Z",
"language": "en",
"source": "phone",
"structured": {
"title": "Feature Discussion",
"overview": "Brainstorming session for new features",
"emoji": "💼",
"category": "business",
"action_items": [],
"events": []
},
"transcript_segments": [
{
"id": "seg_001",
"text": "Let's discuss the new feature",
"speaker_id": 0,
"speaker_name": "John",
"start": 0.0,
"end": 2.5
},
{
"id": "seg_002",
"text": "I think we should focus on the user interface first",
"speaker_id": 1,
"speaker_name": "Speaker 1",
"start": 2.5,
"end": 5.8
}
],
"folder_id": "folder_uuid",
"folder_name": "Work",
"geolocation": {
"latitude": 37.7749295,
"longitude": -122.4194155,
"address": "1 Market St, San Francisco, CA 94105, USA",
"google_place_id": "ChIJIQBpAG2ahYAR_6128GcTUEo",
"location_type": "street_address"
}
}
]
Response Fields
Response Fields
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier |
created_at | datetime | When the conversation record was created |
started_at | datetime | When the conversation started |
finished_at | datetime | When the conversation ended |
language | string | Language code (e.g., “en”) |
source | string | Source device/app |
structured | object | AI-generated structured data |
transcript_segments | array | Transcript segments (if include_transcript=true) |
folder_id | string | Folder ID the conversation belongs to (optional) |
folder_name | string | Folder name, resolved from the user’s folder settings. Null if no folder is assigned. (optional) |
geolocation | object | Location where conversation occurred (if available) |
Transcript Segment Fields
Transcript Segment Fields
| Field | Type | Description |
|---|---|---|
id | string | Segment identifier (optional) |
text | string | The transcribed text |
speaker_id | integer | Numeric speaker identifier (optional) |
speaker_name | string | Human-readable speaker name. Resolved from user profiles or the People database. Falls back to a generic name like “Speaker 1” if unidentified. (optional) |
start | float | Start timestamp in seconds |
end | float | End timestamp in seconds |
Geolocation Object Fields
Geolocation Object Fields
| Field | Type | Description |
|---|---|---|
latitude | float | Latitude coordinate |
longitude | float | Longitude coordinate |
address | string | Human-readable address (optional) |
google_place_id | string | Google Places API ID (optional) |
location_type | string | Type of location, e.g., “premise”, “street_address” (optional) |
Structured Object Fields
Structured Object Fields
| Field | Type | Description |
|---|---|---|
title | string | AI-generated title |
overview | string | Summary of the conversation |
emoji | string | Representative emoji |
category | string | Category (work, personal, etc.) |
action_items | array | Extracted action items |
events | array | Extracted calendar events |
Create Conversation from Text
POST /v1/dev/user/conversations
Create a new conversation from text with full AI processing
Request Body
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
text | string | Yes | The conversation text/transcript (1-100,000 characters) |
text_source | string | No | Source type: audio_transcript, message, or other_text (default: other_text) |
text_source_spec | string | No | Additional source info (e.g., ‘email’, ‘slack’, ‘whatsapp’) |
started_at | datetime | No | When conversation started (defaults to now) |
finished_at | datetime | No | When conversation finished (defaults to started_at + 5 minutes) |
language | string | No | Language code (default: ‘en’) |
geolocation | object | No | Geolocation data with latitude and longitude |
- cURL
- Python
- JavaScript
curl -X POST "https://api.omi.me/v1/dev/user/conversations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Meeting notes: Discussed Q1 goals. Action item: prepare budget by Friday.",
"text_source": "other_text",
"text_source_spec": "meeting_notes",
"started_at": "2025-12-06T14:00:00+00:00",
"language": "en"
}'
import requests
response = requests.post(
"https://api.omi.me/v1/dev/user/conversations",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"text": "Meeting notes: Discussed Q1 goals. Action item: prepare budget by Friday.",
"text_source": "other_text",
"text_source_spec": "meeting_notes",
"started_at": "2025-12-06T14:00:00+00:00",
"language": "en"
}
)
conversation = response.json()
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations",
{
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
text: "Meeting notes: Discussed Q1 goals. Action item: prepare budget by Friday.",
text_source: "other_text",
text_source_spec: "meeting_notes",
started_at: "2025-12-06T14:00:00+00:00",
language: "en"
})
}
);
const conversation = await response.json();
Response Example
Response Example
{
"id": "conv_456",
"status": "completed",
"discarded": false
}
Processing Pipeline
Processing Pipeline
When you create a conversation, the following happens automatically:
- Discard Detection: Determines if content is meaningful enough to save
- Structured Generation: Creates title, overview, category, and emoji
- Action Item Extraction: Identifies and creates action items (with deduplication against past 2 days)
- Memory Extraction: Extracts interesting facts and insights (up to 4 per conversation)
- App Integration: Triggers enabled summarization apps
- Webhooks: Notifies external systems
Memories and action items are extracted asynchronously. Use the GET endpoints to retrieve them after creation.
Create Conversation from Transcript Segments
POST /v1/dev/user/conversations/from-segments
Create from structured transcript with speaker diarization
Request Body
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
transcript_segments | array | Yes | List of transcript segments (1-500 segments) |
source | string | No | Source of conversation (default: external_integration) |
started_at | datetime | No | When conversation started (defaults to now) |
finished_at | datetime | No | When conversation finished (calculated from last segment if not provided) |
language | string | No | Language code (default: ‘en’) |
geolocation | object | No | Geolocation data |
Transcript Segment Fields
Transcript Segment Fields
| Field | Type | Required | Description |
|---|---|---|---|
text | string | Yes | The spoken text |
speaker | string | No | Speaker identifier (e.g., ‘SPEAKER_00’, ‘SPEAKER_01’). Default: ‘SPEAKER_00’ |
speaker_id | integer | No | Numeric speaker ID (auto-calculated if not provided) |
is_user | boolean | No | Whether this segment is from the user. Default: false |
person_id | string | No | ID of known person speaking |
start | float | Yes | Start time in seconds (e.g., 0.0, 1.5, 60.2) |
end | float | Yes | End time in seconds (e.g., 1.5, 3.0, 65.8) |
Available Sources
Available Sources
omi, friend, openglass, phone, desktop, apple_watch, bee, plaud, frame, screenpipe, workflow, sdcard, external_integration- cURL
- Python
- JavaScript
curl -X POST "https://api.omi.me/v1/dev/user/conversations/from-segments" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"transcript_segments": [
{
"text": "Let'\''s review the quarterly results",
"speaker": "SPEAKER_00",
"is_user": true,
"start": 0.0,
"end": 3.5
},
{
"text": "Revenue is up 25% from last quarter",
"speaker": "SPEAKER_01",
"is_user": false,
"start": 4.0,
"end": 7.2
}
],
"source": "phone",
"language": "en"
}'
import requests
response = requests.post(
"https://api.omi.me/v1/dev/user/conversations/from-segments",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"transcript_segments": [
{
"text": "Let's review the quarterly results",
"speaker": "SPEAKER_00",
"is_user": True,
"start": 0.0,
"end": 3.5
},
{
"text": "Revenue is up 25% from last quarter",
"speaker": "SPEAKER_01",
"is_user": False,
"start": 4.0,
"end": 7.2
}
],
"source": "phone",
"language": "en"
}
)
conversation = response.json()
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations/from-segments",
{
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
transcript_segments: [
{
text: "Let's review the quarterly results",
speaker: "SPEAKER_00",
is_user: true,
start: 0.0,
end: 3.5
},
{
text: "Revenue is up 25% from last quarter",
speaker: "SPEAKER_01",
is_user: false,
start: 4.0,
end: 7.2
}
],
source: "phone",
language: "en"
})
}
);
const conversation = await response.json();
Response Example
Response Example
{
"id": "conv_789",
"status": "completed",
"discarded": false
}
Unlike text-based conversations, transcript segments ARE stored in the
transcript_segments field and can be retrieved with include_transcript=true.Get Single Conversation
GET /v1/dev/user/conversations/{conversation_id}
Retrieve a single conversation by ID
Path Parameters
Path Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id | string | The ID of the conversation to retrieve |
Query Parameters
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
include_transcript | boolean | false | Include full transcript segments |
- cURL
- Python
- JavaScript
curl -H "Authorization: Bearer $API_KEY" \
"https://api.omi.me/v1/dev/user/conversations/conv_456?include_transcript=true"
import requests
response = requests.get(
"https://api.omi.me/v1/dev/user/conversations/conv_456",
headers={"Authorization": f"Bearer {API_KEY}"},
params={"include_transcript": True}
)
conversation = response.json()
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations/conv_456?include_transcript=true",
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const conversation = await response.json();
Response Example
Response Example
{
"id": "conv_456",
"created_at": "2025-01-20T13:50:00Z",
"started_at": "2025-01-20T13:50:00Z",
"finished_at": "2025-01-20T14:10:00Z",
"language": "en",
"source": "external_integration",
"structured": {
"title": "Q1 Goals Discussion",
"overview": "Meeting to discuss quarterly goals and budget preparation",
"emoji": "📊",
"category": "business",
"action_items": [
{
"description": "Prepare budget by Friday",
"completed": false
}
],
"events": []
},
"geolocation": {
"latitude": 37.7749295,
"longitude": -122.4194155,
"address": "1 Market St, San Francisco, CA 94105, USA",
"google_place_id": "ChIJIQBpAG2ahYAR_6128GcTUEo",
"location_type": "street_address"
}
}
Update Conversation
PATCH /v1/dev/user/conversations/{conversation_id}
Update a conversation’s title or discard status
Path Parameters
Path Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id | string | The ID of the conversation to update |
Request Body
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
title | string | No | New title (1-500 characters) |
discarded | boolean | No | Whether the conversation is discarded |
- cURL
- Python
- JavaScript
curl -X PATCH "https://api.omi.me/v1/dev/user/conversations/conv_456" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Q1 Planning Meeting - Budget Discussion"
}'
import requests
response = requests.patch(
"https://api.omi.me/v1/dev/user/conversations/conv_456",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={"title": "Q1 Planning Meeting - Budget Discussion"}
)
conversation = response.json()
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations/conv_456",
{
method: "PATCH",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
title: "Q1 Planning Meeting - Budget Discussion"
})
}
);
const conversation = await response.json();
Response Example
Response Example
{
"id": "conv_456",
"created_at": "2025-01-20T13:50:00Z",
"started_at": "2025-01-20T13:50:00Z",
"finished_at": "2025-01-20T14:10:00Z",
"language": "en",
"source": "external_integration",
"structured": {
"title": "Q1 Planning Meeting - Budget Discussion",
"overview": "Meeting to discuss quarterly goals and budget preparation",
"emoji": "📊",
"category": "business",
"action_items": [],
"events": []
},
"geolocation": {
"latitude": 37.7749295,
"longitude": -122.4194155,
"address": "1 Market St, San Francisco, CA 94105, USA",
"google_place_id": "ChIJIQBpAG2ahYAR_6128GcTUEo",
"location_type": "street_address"
}
}
Use
discarded: true to hide a conversation from the main list without permanently deleting it.Delete Conversation
DELETE /v1/dev/user/conversations/{conversation_id}
Delete a conversation permanently
Path Parameters
Path Parameters
| Parameter | Type | Description |
|---|---|---|
conversation_id | string | The ID of the conversation to delete |
- cURL
- Python
- JavaScript
curl -X DELETE "https://api.omi.me/v1/dev/user/conversations/conv_456" \
-H "Authorization: Bearer $API_KEY"
import requests
response = requests.delete(
"https://api.omi.me/v1/dev/user/conversations/conv_456",
headers={"Authorization": f"Bearer {API_KEY}"}
)
result = response.json()
if result["success"]:
print("Conversation deleted successfully")
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations/conv_456",
{
method: "DELETE",
headers: { Authorization: `Bearer ${API_KEY}` }
}
);
const result = await response.json();
if (result.success) {
console.log("Conversation deleted successfully");
}
Response Example
Response Example
{
"success": true
}
This action is permanent. Deleted conversations and their associated photos cannot be recovered. Consider using
PATCH with discarded: true to hide a conversation instead.Use Case: Upload Meeting Transcript
- Python
- JavaScript
import requests
from datetime import datetime, timezone
API_KEY = "omi_dev_your_api_key"
# Your meeting transcript with speaker diarization
transcript = [
{"speaker": "SPEAKER_00", "text": "Welcome everyone to the standup", "start": 0.0, "end": 2.5},
{"speaker": "SPEAKER_01", "text": "Thanks. I finished the API integration yesterday", "start": 3.0, "end": 6.2},
{"speaker": "SPEAKER_00", "text": "Great work! Any blockers?", "start": 6.5, "end": 8.0},
{"speaker": "SPEAKER_01", "text": "Just waiting on the design review", "start": 8.3, "end": 10.5},
]
# Convert to Omi format
segments = [
{
"text": seg["text"],
"speaker": seg["speaker"],
"is_user": seg["speaker"] == "SPEAKER_00",
"start": seg["start"],
"end": seg["end"]
}
for seg in transcript
]
# Create conversation
response = requests.post(
"https://api.omi.me/v1/dev/user/conversations/from-segments",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={
"transcript_segments": segments,
"source": "phone",
"started_at": datetime.now(timezone.utc).isoformat(),
"language": "en"
}
)
result = response.json()
print(f"Created conversation: {result['id']}")
print(f"Status: {result['status']}")
print(f"Discarded: {result['discarded']}")
const API_KEY = process.env.OMI_API_KEY;
// Your meeting transcript with speaker diarization
const transcript = [
{ speaker: "SPEAKER_00", text: "Welcome everyone to the standup", start: 0.0, end: 2.5 },
{ speaker: "SPEAKER_01", text: "Thanks. I finished the API integration yesterday", start: 3.0, end: 6.2 },
{ speaker: "SPEAKER_00", text: "Great work! Any blockers?", start: 6.5, end: 8.0 },
{ speaker: "SPEAKER_01", text: "Just waiting on the design review", start: 8.3, end: 10.5 },
];
// Convert to Omi format
const segments = transcript.map(seg => ({
text: seg.text,
speaker: seg.speaker,
is_user: seg.speaker === "SPEAKER_00",
start: seg.start,
end: seg.end
}));
// Create conversation
const response = await fetch(
"https://api.omi.me/v1/dev/user/conversations/from-segments",
{
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
transcript_segments: segments,
source: "phone",
started_at: new Date().toISOString(),
language: "en"
})
}
);
const result = await response.json();
console.log(`Created conversation: ${result.id}`);
console.log(`Status: ${result.status}`);
console.log(`Discarded: ${result.discarded}`);
Use Case: Export Conversations
- Bash
- Python
- JavaScript
#!/bin/bash
API_KEY="omi_dev_your_api_key"
# Export all conversations with transcripts
curl -H "Authorization: Bearer $API_KEY" \
"https://api.omi.me/v1/dev/user/conversations?limit=1000&include_transcript=true" \
> conversations_backup.json
echo "Exported conversations to conversations_backup.json"
import requests
import json
API_KEY = "omi_dev_your_api_key"
# Paginate through all conversations
all_conversations = []
offset = 0
limit = 100
while True:
response = requests.get(
"https://api.omi.me/v1/dev/user/conversations",
headers={"Authorization": f"Bearer {API_KEY}"},
params={
"limit": limit,
"offset": offset,
"include_transcript": True
}
)
conversations = response.json()
if not conversations:
break
all_conversations.extend(conversations)
offset += limit
print(f"Fetched {len(all_conversations)} conversations...")
# Save to file
with open("conversations_backup.json", "w") as f:
json.dump(all_conversations, f, indent=2)
print(f"Exported {len(all_conversations)} conversations")
const fs = require('fs');
const API_KEY = process.env.OMI_API_KEY;
async function exportConversations() {
const allConversations = [];
let offset = 0;
const limit = 100;
while (true) {
const response = await fetch(
`https://api.omi.me/v1/dev/user/conversations?limit=${limit}&offset=${offset}&include_transcript=true`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
const conversations = await response.json();
if (conversations.length === 0) break;
allConversations.push(...conversations);
offset += limit;
console.log(`Fetched ${allConversations.length} conversations...`);
}
fs.writeFileSync(
'conversations_backup.json',
JSON.stringify(allConversations, null, 2)
);
console.log(`Exported ${allConversations.length} conversations`);
}
exportConversations();