Back to Omi

Conversations

docs/doc/developer/api/conversations.mdx

3.0.0-Android-App27.8 KB
Original Source

Endpoints

<CardGroup cols={3}> <Card title="GET" icon="download" color="#22c55e"> Retrieve conversations </Card> <Card title="GET Single" icon="file" color="#22c55e"> Get one conversation </Card> <Card title="POST" icon="upload" color="#3b82f6"> Create from text </Card> <Card title="PATCH" icon="pen" color="#a855f7"> Update conversation </Card> <Card title="DELETE" icon="trash" color="#ef4444"> Delete conversation </Card> <Card title="POST Segments" icon="waveform-lines" color="#3b82f6"> Create from transcript </Card> </CardGroup>

Get Conversations

<Card title="GET /v1/dev/user/conversations" icon="download" color="#22c55e" horizontal> Retrieve your conversation transcripts (only completed, non-discarded) </Card> <AccordionGroup> <Accordion title="Query Parameters" icon="sliders" defaultOpen={true}> | 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 | </Accordion> </AccordionGroup> <Tabs> <Tab title="cURL"> ```bash curl -H "Authorization: Bearer $API_KEY" \ "https://api.omi.me/v1/dev/user/conversations?limit=10&include_transcript=true" ``` </Tab> <Tab title="Python"> ```python 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()
```
</Tab> <Tab title="JavaScript"> ```javascript 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(); ``` </Tab> </Tabs> <AccordionGroup> <Accordion title="Response (without transcript)" icon="code" defaultOpen={true}> ```json [ { "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": [] }, "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" } } ] ``` </Accordion> <Accordion title="Response (with transcript)" icon="waveform-lines"> ```json [ { "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 } ], "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" } } ] ``` </Accordion> <Accordion title="Response Fields" icon="list"> | 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`) | | `geolocation` | object | Location where conversation occurred (if available) | </Accordion> <Accordion title="Transcript Segment Fields" icon="waveform-lines"> | 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 | </Accordion> <Accordion title="Geolocation Object Fields" icon="location-dot"> | 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) | </Accordion> <Accordion title="Structured Object Fields" icon="sitemap"> | 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 | </Accordion> </AccordionGroup>

Create Conversation from Text

<Card title="POST /v1/dev/user/conversations" icon="upload" color="#3b82f6" horizontal> Create a new conversation from text with full AI processing </Card> <AccordionGroup> <Accordion title="Request Body" icon="code" defaultOpen={true}> | 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` | </Accordion> </AccordionGroup> <Tabs> <Tab title="cURL"> ```bash 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" }' ``` </Tab> <Tab title="Python"> ```python 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()
```
</Tab> <Tab title="JavaScript"> ```javascript 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(); ``` </Tab> </Tabs> <Accordion title="Response Example" icon="code" defaultOpen={true}> ```json { "id": "conv_456", "status": "completed", "discarded": false } ``` </Accordion> <AccordionGroup> <Accordion title="Processing Pipeline" icon="diagram-project" defaultOpen={true}> 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
</Accordion> </AccordionGroup> <Note> Memories and action items are extracted asynchronously. Use the GET endpoints to retrieve them after creation. </Note>

Create Conversation from Transcript Segments

<Card title="POST /v1/dev/user/conversations/from-segments" icon="waveform-lines" color="#3b82f6" horizontal> Create from structured transcript with speaker diarization </Card> <AccordionGroup> <Accordion title="Request Body" icon="code" defaultOpen={true}> | 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 | </Accordion> <Accordion title="Transcript Segment Fields" icon="list"> | 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) | </Accordion> <Accordion title="Available Sources" icon="microchip"> `omi`, `friend`, `openglass`, `phone`, `desktop`, `apple_watch`, `bee`, `plaud`, `frame`, `screenpipe`, `workflow`, `sdcard`, `external_integration` </Accordion> </AccordionGroup> <Tabs> <Tab title="cURL"> ```bash 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" }' ``` </Tab> <Tab title="Python"> ```python 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()
```
</Tab> <Tab title="JavaScript"> ```javascript 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(); ``` </Tab> </Tabs> <Accordion title="Response Example" icon="code" defaultOpen={true}> ```json { "id": "conv_789", "status": "completed", "discarded": false } ``` </Accordion> <Note> Unlike text-based conversations, transcript segments ARE stored in the `transcript_segments` field and can be retrieved with `include_transcript=true`. </Note>

Get Single Conversation

<Card title="GET /v1/dev/user/conversations/{conversation_id}" icon="file" color="#22c55e" horizontal> Retrieve a single conversation by ID </Card> <AccordionGroup> <Accordion title="Path Parameters" icon="route" defaultOpen={true}> | Parameter | Type | Description | |-----------|------|-------------| | `conversation_id` | string | The ID of the conversation to retrieve | </Accordion> <Accordion title="Query Parameters" icon="sliders" defaultOpen={true}> | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `include_transcript` | boolean | false | Include full transcript segments | </Accordion> </AccordionGroup> <Tabs> <Tab title="cURL"> ```bash curl -H "Authorization: Bearer $API_KEY" \ "https://api.omi.me/v1/dev/user/conversations/conv_456?include_transcript=true" ``` </Tab> <Tab title="Python"> ```python 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()
```
</Tab> <Tab title="JavaScript"> ```javascript 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(); ``` </Tab> </Tabs> <Accordion title="Response Example" icon="code" defaultOpen={true}> ```json { "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" } } ``` </Accordion>

Update Conversation

<Card title="PATCH /v1/dev/user/conversations/{conversation_id}" icon="pen" color="#a855f7" horizontal> Update a conversation's title or discard status </Card> <AccordionGroup> <Accordion title="Path Parameters" icon="route" defaultOpen={true}> | Parameter | Type | Description | |-----------|------|-------------| | `conversation_id` | string | The ID of the conversation to update | </Accordion> <Accordion title="Request Body" icon="code" defaultOpen={true}> | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `title` | string | No | New title (1-500 characters) | | `discarded` | boolean | No | Whether the conversation is discarded |
At least one field must be provided.
</Accordion> </AccordionGroup> <Tabs> <Tab title="cURL"> ```bash 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" }' ``` </Tab> <Tab title="Python"> ```python 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()
```
</Tab> <Tab title="JavaScript"> ```javascript 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(); ``` </Tab> </Tabs> <Accordion title="Response Example" icon="code" defaultOpen={true}> ```json { "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" } } ``` </Accordion> <Tip> Use `discarded: true` to hide a conversation from the main list without permanently deleting it. </Tip>

Delete Conversation

<Card title="DELETE /v1/dev/user/conversations/{conversation_id}" icon="trash" color="#ef4444" horizontal> Delete a conversation permanently </Card> <AccordionGroup> <Accordion title="Path Parameters" icon="route" defaultOpen={true}> | Parameter | Type | Description | |-----------|------|-------------| | `conversation_id` | string | The ID of the conversation to delete | </Accordion> </AccordionGroup> <Tabs> <Tab title="cURL"> ```bash curl -X DELETE "https://api.omi.me/v1/dev/user/conversations/conv_456" \ -H "Authorization: Bearer $API_KEY" ``` </Tab> <Tab title="Python"> ```python 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")
```
</Tab> <Tab title="JavaScript"> ```javascript 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"); } ``` </Tab> </Tabs> <Accordion title="Response Example" icon="code" defaultOpen={true}> ```json { "success": true } ``` </Accordion> <Warning> This action is permanent. Deleted conversations and their associated photos cannot be recovered. Consider using `PATCH` with `discarded: true` to hide a conversation instead. </Warning>

Use Case: Upload Meeting Transcript

<Tabs> <Tab title="Python"> ```python 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']}")
```
</Tab> <Tab title="JavaScript"> ```javascript 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}`);
```
</Tab> </Tabs>

Use Case: Export Conversations

<Tabs> <Tab title="Bash"> ```bash #!/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"
```
</Tab> <Tab title="Python"> ```python 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")
```
</Tab> <Tab title="JavaScript"> ```javascript 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();
```
</Tab> </Tabs>