Skip to content

Latest commit

 

History

History
917 lines (836 loc) · 28.8 KB

File metadata and controls

917 lines (836 loc) · 28.8 KB
title Conversations
icon message
description Create and retrieve conversations via the Developer API

Endpoints

Retrieve conversations Get one conversation Create from text Update conversation Delete conversation Create from transcript

Get Conversations

Retrieve your conversation transcripts (only completed, non-discarded) | 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. | ```bash curl -H "Authorization: Bearer $API_KEY" \ "https://api.omi.me/v1/dev/user/conversations?limit=10&include_transcript=true" ``` ```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()
```
```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(); ``` ```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": [] }, "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" } } ] ``` ```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 } ], "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" } } ] ``` | 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) | | 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 | | 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) | | 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

Create a new conversation from text with full AI processing | 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` | ```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" }' ``` ```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()
```
```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(); ``` ```json { "id": "conv_456", "status": "completed", "discarded": false } ``` 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

Create from structured transcript with speaker diarization | 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 | | 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) | `omi`, `friend`, `openglass`, `phone`, `desktop`, `apple_watch`, `bee`, `plaud`, `frame`, `screenpipe`, `workflow`, `sdcard`, `external_integration` ```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" }' ``` ```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()
```
```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(); ``` ```json { "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

Retrieve a single conversation by ID | Parameter | Type | Description | |-----------|------|-------------| | `conversation_id` | string | The ID of the conversation to retrieve | | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `include_transcript` | boolean | false | Include full transcript segments | ```bash curl -H "Authorization: Bearer $API_KEY" \ "https://api.omi.me/v1/dev/user/conversations/conv_456?include_transcript=true" ``` ```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()
```
```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(); ``` ```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" } } ```

Update Conversation

Update a conversation's title or discard status | Parameter | Type | Description | |-----------|------|-------------| | `conversation_id` | string | The ID of the conversation to update | | 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.
```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" }' ``` ```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()
```
```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(); ``` ```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" } } ``` Use `discarded: true` to hide a conversation from the main list without permanently deleting it.

Delete Conversation

Delete a conversation permanently | Parameter | Type | Description | |-----------|------|-------------| | `conversation_id` | string | The ID of the conversation to delete | ```bash curl -X DELETE "https://api.omi.me/v1/dev/user/conversations/conv_456" \ -H "Authorization: Bearer $API_KEY" ``` ```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")
```
```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"); } ``` ```json { "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 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']}")
```
```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}`);
```

Use Case: Export Conversations

```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"
```
```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")
```
```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();
```