# Create Action Item Source: https://docs.omi.me/api-reference/action-items/create-action-item /api-reference/openapi.json post /v1/dev/user/action-items Create a new action item for the authenticated user. - **description**: The action item description (1-500 characters) - **completed**: Whether the action item is completed (default: False) - **due_at**: Optional due date in ISO 8601 format with timezone # Create Action Items Batch Source: https://docs.omi.me/api-reference/action-items/create-action-items-batch /api-reference/openapi.json post /v1/dev/user/action-items/batch Create multiple action items in a batch. - **action_items**: List of action items to create (max 50) # Delete Action Item Source: https://docs.omi.me/api-reference/action-items/delete-action-item /api-reference/openapi.json delete /v1/dev/user/action-items/{action_item_id} Delete an action item by ID. - **action_item_id**: The ID of the action item to delete # Get Action Items Source: https://docs.omi.me/api-reference/action-items/get-action-items /api-reference/openapi.json get /v1/dev/user/action-items Get action items with optional filters. Locked action items are excluded. - **conversation_id**: Filter by conversation ID (None for standalone items) - **completed**: Filter by completion status - **start_date**: Filter by start date (inclusive) - **end_date**: Filter by end date (inclusive) - **limit**: Maximum number of items to return - **offset**: Number of items to skip # Update Action Item Source: https://docs.omi.me/api-reference/action-items/update-action-item /api-reference/openapi.json patch /v1/dev/user/action-items/{action_item_id} Update an action item. - **action_item_id**: The ID of the action item to update - **description**: New description (optional) - **completed**: New completion status (optional) - **due_at**: New due date (optional, set to null to remove) # Create Key Source: https://docs.omi.me/api-reference/api-keys/create-key /api-reference/openapi.json post /v1/dev/keys Create a new Developer API key with optional scopes. - **name**: Descriptive name for the key - **scopes**: Optional list of scopes. If not provided, defaults to read-only access. Available scopes: - conversations:read - conversations:write - memories:read - memories:write - action_items:read - action_items:write - goals:read - goals:write # Delete Key Source: https://docs.omi.me/api-reference/api-keys/delete-key /api-reference/openapi.json delete /v1/dev/keys/{key_id} # Get calling API key Source: https://docs.omi.me/api-reference/api-keys/get-calling-api-key /api-reference/openapi.json get /v1/dev/key Return only the calling key's metadata and effective scopes. No data scope is required. # Get Keys Source: https://docs.omi.me/api-reference/api-keys/get-keys /api-reference/openapi.json get /v1/dev/keys # Ask Conversations Source: https://docs.omi.me/api-reference/conversations/ask-conversations /api-reference/openapi.json post /v1/dev/user/ask Answer a natural-language question grounded in the user's own conversations. Semantically searches the user's conversations for the question, then synthesizes a cited answer from the most relevant ones — the same retrieval + RAG the chat surface uses, exposed for headless / Developer-API callers (CLI, CI, scripts). Read-only: it never writes; discarded conversations are excluded from retrieval and locked conversations are re-checked on the authoritative record before any go to the LLM. # Create Conversation Source: https://docs.omi.me/api-reference/conversations/create-conversation /api-reference/openapi.json post /v1/dev/user/conversations Create a new conversation from text for the authenticated user. This endpoint processes the provided text through the full conversation pipeline: - Generates structured data (title, overview, category, emoji) - Extracts action items (with deduplication) - Extracts memories (with quality filtering) - Determines if conversation should be discarded - Triggers app integrations - Triggers webhooks **Request Parameters:** - **text**: The conversation text/transcript (1-100,000 characters) - **text_source**: Source type - audio_transcript, message, or other_text (default: other_text) - **text_source_spec**: Additional source info (e.g., 'email', 'slack') - **started_at**: When conversation started (defaults to now) - **finished_at**: When conversation finished (defaults to started_at + 5 minutes) - **language**: Language code (default: 'en') - **geolocation**: Optional geolocation data **Response:** - Returns the created conversation ID and status - Use GET /v1/dev/user/conversations/{id} to retrieve full details # Create Conversation From Segments Source: https://docs.omi.me/api-reference/conversations/create-conversation-from-segments /api-reference/openapi.json post /v1/dev/user/conversations/from-segments Create a new conversation from structured transcript segments. This endpoint is for advanced integrations that have speaker diarization and timing information. It processes the transcript segments through the full conversation pipeline. **Transcript Segments:** - **text**: The text spoken (required) - **speaker**: Speaker identifier like 'SPEAKER_00', 'SPEAKER_01' (default: 'SPEAKER_00') - **speaker_id**: Numeric speaker ID (auto-calculated from speaker if not provided) - **is_user**: Whether this segment is from the user (default: False) - **person_id**: ID of known person speaking (optional) - **start**: Start time in seconds, e.g., 0.0, 1.5, 60.2 (required) - **end**: End time in seconds, e.g., 1.5, 3.0, 65.8 (required) **Other Parameters:** - **source**: Source of conversation (default: external_integration). Options: - omi, friend, openglass, phone, desktop, apple_watch, bee, plaud, frame, etc. - **started_at**: When conversation started (defaults to now) - **finished_at**: When conversation finished (calculated from last segment if not provided) - **language**: Language code (default: 'en') - **geolocation**: Optional geolocation data **Example:** ```json { "transcript_segments": [ { "text": "Hey, how are you doing?", "speaker": "SPEAKER_00", "is_user": true, "start": 0.0, "end": 2.5 }, { "text": "I'm doing great, thanks!", "speaker": "SPEAKER_01", "is_user": false, "start": 2.8, "end": 5.2 } ], "source": "phone", "language": "en" } ``` # Delete Conversation Endpoint Source: https://docs.omi.me/api-reference/conversations/delete-conversation-endpoint /api-reference/openapi.json delete /v1/dev/user/conversations/{conversation_id} Delete a conversation by ID. This also deletes any associated photos in the conversation's subcollection. - **conversation_id**: The ID of the conversation to delete # Get Conversation Endpoint Source: https://docs.omi.me/api-reference/conversations/get-conversation-endpoint /api-reference/openapi.json get /v1/dev/user/conversations/{conversation_id} Get a single conversation by ID. - **conversation_id**: The ID of the conversation to retrieve - **include_transcript**: If True, includes full transcript_segments in the response # Get Conversations Source: https://docs.omi.me/api-reference/conversations/get-conversations /api-reference/openapi.json get /v1/dev/user/conversations Get conversations with optional transcript inclusion. - **include_transcript**: If True, includes full transcript_segments in the response - **folder_id**: Filter by folder ID (must be a non-empty string if provided) - **starred**: Filter by starred status (true/false) # Update Conversation Endpoint Source: https://docs.omi.me/api-reference/conversations/update-conversation-endpoint /api-reference/openapi.json patch /v1/dev/user/conversations/{conversation_id} Update a conversation's title or discard status. - **conversation_id**: The ID of the conversation to update - **title**: New title for the conversation (optional) - **discarded**: Whether the conversation is discarded (optional) # Get Developer Daily Summaries Source: https://docs.omi.me/api-reference/daily-summaries/get-developer-daily-summaries /api-reference/openapi.json get /v1/dev/user/daily-summaries List the authenticated user's stored daily recaps. Daily summaries are derived from conversations, so this read uses the same `conversations:read` scope and aggregate read budget as conversation lists. # Get Developer Daily Summary Source: https://docs.omi.me/api-reference/daily-summaries/get-developer-daily-summary /api-reference/openapi.json get /v1/dev/user/daily-summaries/{summary_id} Get one stored daily recap by ID. # Search Memories Vector Source: https://docs.omi.me/api-reference/developer/search-memories-vector /api-reference/openapi.json get /v1/dev/user/memories/vector/search Search developer-readable default memory memory through hydrated vector candidates. This narrow developer API vector endpoint fails closed unless the authenticated Developer API app/key has a verified memories.read scope and a persisted app/key default-read grant. Vector hits are hydrated through the universal repository against authoritative `users/{uid}/memory_items` before returning results, so stale Short-term and Archive remain unavailable by default. # Create Action Item Source: https://docs.omi.me/api-reference/endpoint/action-items/create POST /v1/dev/user/action-items Create a new action item for the authenticated user. - **description**: The action item description (1-500 characters) - **completed**: Whether the action item is completed (default: False) - **due_at**: Optional due date in ISO 8601 format with timezone # Create Action Items (Batch) Source: https://docs.omi.me/api-reference/endpoint/action-items/create-batch POST /v1/dev/user/action-items/batch Create multiple action items in a batch. - **action_items**: List of action items to create (max 50) # Delete Action Item Source: https://docs.omi.me/api-reference/endpoint/action-items/delete DELETE /v1/dev/user/action-items/{action_item_id} Delete an action item by ID. - **action_item_id**: The ID of the action item to delete # List Action Items Source: https://docs.omi.me/api-reference/endpoint/action-items/list GET /v1/dev/user/action-items Get action items with optional filters. Locked action items are excluded. - **conversation_id**: Filter by conversation ID (None for standalone items) - **completed**: Filter by completion status - **start_date**: Filter by start date (inclusive) - **end_date**: Filter by end date (inclusive) - **limit**: Maximum number of items to return - **offset**: Number of items to skip # Update Action Item Source: https://docs.omi.me/api-reference/endpoint/action-items/update PATCH /v1/dev/user/action-items/{action_item_id} Update an action item. - **action_item_id**: The ID of the action item to update - **description**: New description (optional) - **completed**: New completion status (optional) - **due_at**: New due date (optional, set to null to remove) # Create Conversation Source: https://docs.omi.me/api-reference/endpoint/conversations/create POST /v1/dev/user/conversations Create a new conversation from text for the authenticated user. This endpoint processes the provided text through the full conversation pipeline: - Generates structured data (title, overview, category, emoji) - Extracts action items (with deduplication) - Extracts memories (with quality filtering) - Determines if conversation should be discarded - Triggers app integrations - Triggers webhooks **Request Parameters:** - **text**: The conversation text/transcript (1-100,000 characters) - **text_source**: Source type - audio_transcript, message, or other_text (default: other_text) - **text_source_spec**: Additional source info (e.g., 'email', 'slack') - **started_at**: When conversation started (defaults to now) - **finished_at**: When conversation finished (defaults to started_at + 5 minutes) - **language**: Language code (default: 'en') - **geolocation**: Optional geolocation data **Response:** - Returns the created conversation ID and status - Use GET /v1/dev/user/conversations/{id} to retrieve full details # Create from Transcript Segments Source: https://docs.omi.me/api-reference/endpoint/conversations/create-from-segments POST /v1/dev/user/conversations/from-segments Create a new conversation from structured transcript segments. This endpoint is for advanced integrations that have speaker diarization and timing information. It processes the transcript segments through the full conversation pipeline. **Transcript Segments:** - **text**: The text spoken (required) - **speaker**: Speaker identifier like 'SPEAKER_00', 'SPEAKER_01' (default: 'SPEAKER_00') - **speaker_id**: Numeric speaker ID (auto-calculated from speaker if not provided) - **is_user**: Whether this segment is from the user (default: False) - **person_id**: ID of known person speaking (optional) - **start**: Start time in seconds, e.g., 0.0, 1.5, 60.2 (required) - **end**: End time in seconds, e.g., 1.5, 3.0, 65.8 (required) **Other Parameters:** - **source**: Source of conversation (default: external_integration). Options: - omi, friend, openglass, phone, desktop, apple_watch, bee, plaud, frame, etc. - **started_at**: When conversation started (defaults to now) - **finished_at**: When conversation finished (calculated from last segment if not provided) - **language**: Language code (default: 'en') - **geolocation**: Optional geolocation data **Example:** ```json { "transcript_segments": [ { "text": "Hey, how are you doing?", "speaker": "SPEAKER_00", "is_user": true, "start": 0.0, "end": 2.5 }, { "text": "I'm doing great, thanks!", "speaker": "SPEAKER_01", "is_user": false, "start": 2.8, "end": 5.2 } ], "source": "phone", "language": "en" } ``` # Delete Conversation Source: https://docs.omi.me/api-reference/endpoint/conversations/delete DELETE /v1/dev/user/conversations/{conversation_id} Delete a conversation by ID. This also deletes any associated photos in the conversation's subcollection. - **conversation_id**: The ID of the conversation to delete # Get Conversation Source: https://docs.omi.me/api-reference/endpoint/conversations/get GET /v1/dev/user/conversations/{conversation_id} Get a single conversation by ID. - **conversation_id**: The ID of the conversation to retrieve - **include_transcript**: If True, includes full transcript_segments in the response # List Conversations Source: https://docs.omi.me/api-reference/endpoint/conversations/list GET /v1/dev/user/conversations Get conversations with optional transcript inclusion. - **include_transcript**: If True, includes full transcript_segments in the response - **folder_id**: Filter by folder ID (must be a non-empty string if provided) - **starred**: Filter by starred status (true/false) # Update Conversation Source: https://docs.omi.me/api-reference/endpoint/conversations/update PATCH /v1/dev/user/conversations/{conversation_id} Update a conversation's title or discard status. - **conversation_id**: The ID of the conversation to update - **title**: New title for the conversation (optional) - **discarded**: Whether the conversation is discarded (optional) # List Folders Source: https://docs.omi.me/api-reference/endpoint/folders/list GET /v1/dev/user/folders Get all folders for the authenticated user. This endpoint is strictly read-only and returns an empty list if the user has no folders. Unlike the internal `/v1/folders` endpoint, it does NOT call `initialize_system_folders`, because doing so under a `conversations:read` scope would silently write to Firestore (violating the read-only contract) and opens a TOCTOU window where concurrent first requests can race past the outer empty-check and create duplicate system folders. System folders (Work, Personal, Social) are still initialized lazily through other paths: - The mobile app calls the internal `GET /v1/folders` whenever the conversations screen is rendered (`app/lib/pages/conversations/conversations_page.dart`), which triggers `initialize_system_folders` on first access. - The conversation post-processing pipeline calls `initialize_system_folders` whenever a new conversation is created (`backend/utils/conversations/process_conversation.py`). In practice, any user who can issue a Developer API key has already gone through one of those paths, so the empty-list case here only affects users who have never opened the conversations tab nor created a single conversation. # Create API Key Source: https://docs.omi.me/api-reference/endpoint/keys/create POST /v1/dev/keys Create a new Developer API key with optional scopes. - **name**: Descriptive name for the key - **scopes**: Optional list of scopes. If not provided, defaults to read-only access. Available scopes: - conversations:read - conversations:write - memories:read - memories:write - action_items:read - action_items:write - goals:read - goals:write # Calling API Key Source: https://docs.omi.me/api-reference/endpoint/keys/current GET /v1/dev/key Return only the calling key's metadata and effective scopes. No data scope is required. # List API Keys Source: https://docs.omi.me/api-reference/endpoint/keys/list GET /v1/dev/keys # Revoke API Key Source: https://docs.omi.me/api-reference/endpoint/keys/revoke DELETE /v1/dev/keys/{key_id} # Create Memory Source: https://docs.omi.me/api-reference/endpoint/memories/create POST /v1/dev/user/memories Create a new memory for the authenticated user. - **content**: The content of the memory (1-500 characters) - **category**: Memory category (auto-categorized if not provided) - **visibility**: Visibility: public or private (default: private) - **tags**: List of tags associated with the memory A memory is identified by its text. Sending text the user already has (ignoring surrounding whitespace; case-sensitive) returns that memory unchanged, so retries are safe without extra headers. Use PATCH to change an existing memory's fields. After a delete, the same text creates a new memory. # Create Memories (Batch) Source: https://docs.omi.me/api-reference/endpoint/memories/create-batch POST /v1/dev/user/memories/batch Create multiple memories in a batch. - **memories**: List of memories to create (max 25) Items follow the single-create rule: text the user already has returns the existing memory at that position, so a retried batch creates nothing twice. `created_count` is the number of memories returned. # Delete Memory Source: https://docs.omi.me/api-reference/endpoint/memories/delete DELETE /v1/dev/user/memories/{memory_id} Delete a memory by ID. - **memory_id**: The ID of the memory to delete # List Memories Source: https://docs.omi.me/api-reference/endpoint/memories/list GET /v1/dev/user/memories # Update Memory Source: https://docs.omi.me/api-reference/endpoint/memories/update PATCH /v1/dev/user/memories/{memory_id} Update a memory's content, visibility, tags, or category. - **memory_id**: The ID of the memory to update - **content**: New content for the memory (optional) - **visibility**: New visibility: public or private (optional) - **tags**: New tags for the memory (optional) - **category**: New category for the memory (optional) # Get User Folders Source: https://docs.omi.me/api-reference/folders/get-user-folders /api-reference/openapi.json get /v1/dev/user/folders Get all folders for the authenticated user. This endpoint is strictly read-only and returns an empty list if the user has no folders. Unlike the internal `/v1/folders` endpoint, it does NOT call `initialize_system_folders`, because doing so under a `conversations:read` scope would silently write to Firestore (violating the read-only contract) and opens a TOCTOU window where concurrent first requests can race past the outer empty-check and create duplicate system folders. System folders (Work, Personal, Social) are still initialized lazily through other paths: - The mobile app calls the internal `GET /v1/folders` whenever the conversations screen is rendered (`app/lib/pages/conversations/conversations_page.dart`), which triggers `initialize_system_folders` on first access. - The conversation post-processing pipeline calls `initialize_system_folders` whenever a new conversation is created (`backend/utils/conversations/process_conversation.py`). In practice, any user who can issue a Developer API key has already gone through one of those paths, so the empty-list case here only affects users who have never opened the conversations tab nor created a single conversation. # Create Goal Source: https://docs.omi.me/api-reference/goals/create-goal /api-reference/openapi.json post /v1/dev/user/goals Create a durable goal. Metrics are optional and other goals are never changed implicitly. - **title**: The goal title/description (1-500 characters) - **goal_type**: Optional metric type: boolean, scale, or numeric - **target_value**: Optional target value - **current_value**: Optional current progress - **min_value**: Optional minimum scale value - **max_value**: Optional maximum scale value - **unit**: Optional unit label (e.g., 'users', 'points') Omit all metric fields to create a qualitative goal. # Delete Goal Source: https://docs.omi.me/api-reference/goals/delete-goal /api-reference/openapi.json delete /v1/dev/user/goals/{goal_id} Delete a goal by ID. - **goal_id**: The ID of the goal to delete # Get Goal Source: https://docs.omi.me/api-reference/goals/get-goal /api-reference/openapi.json get /v1/dev/user/goals/{goal_id} Get a single goal by ID. - **goal_id**: The ID of the goal to retrieve # Get Goal History Source: https://docs.omi.me/api-reference/goals/get-goal-history /api-reference/openapi.json get /v1/dev/user/goals/{goal_id}/history Get progress history for a goal. - **goal_id**: The ID of the goal - **days**: Number of days of history to return (max 365, default 30) # Get Goals Source: https://docs.omi.me/api-reference/goals/get-goals /api-reference/openapi.json get /v1/dev/user/goals Get user goals. - **limit**: Maximum number of goals to return - **include_inactive**: If True, includes inactive/completed goals # Update Goal Source: https://docs.omi.me/api-reference/goals/update-goal /api-reference/openapi.json patch /v1/dev/user/goals/{goal_id} Update a goal. - **goal_id**: The ID of the goal to update - **title**: New title (optional) - **target_value**: New target value (optional) - **current_value**: New progress value (optional) - **min_value**: New minimum value (optional) - **max_value**: New maximum value (optional) - **unit**: New unit label (optional) # Update Goal Progress Source: https://docs.omi.me/api-reference/goals/update-goal-progress /api-reference/openapi.json patch /v1/dev/user/goals/{goal_id}/progress Update the progress value of a goal. - **goal_id**: The ID of the goal to update - **current_value**: New progress value (query parameter) # API Reference Source: https://docs.omi.me/api-reference/introduction Complete reference for the Omi Developer API. Build integrations with memories, conversations, action items, and more. ## Base URL ``` https://api.omi.me ``` ## Authentication All API requests require a Developer API key in the `Authorization` header: ```http theme={null} Authorization: Bearer omi_dev_your_api_key_here ``` Get your key from **Settings → Developer → Create Key** in the Omi app. MCP keys (`omi_mcp_...`) are only for the MCP server at `/v1/mcp`. They are not accepted by REST Developer API endpoints. Use a Developer API key (`omi_dev_...`) for endpoints such as `/v1/dev/user/memories` and `/v1/dev/user/conversations`. ## Rate Limits | Limit | Value | | - | - | | Per minute | 100 requests per API key | | Per day | 10,000 requests per user | Rate limit headers are included in every response: ```http theme={null} X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 1642694400 ``` ## Resources Timeless facts about the user — preferences, relationships, insights. Conversation transcripts with AI-generated summaries and action items. Tasks and to-dos extracted from conversations or created manually. Create, list, and revoke developer API keys. # Create Memories Batch Source: https://docs.omi.me/api-reference/memories/create-memories-batch /api-reference/openapi.json post /v1/dev/user/memories/batch Create multiple memories in a batch. - **memories**: List of memories to create (max 25) Items follow the single-create rule: text the user already has returns the existing memory at that position, so a retried batch creates nothing twice. `created_count` is the number of memories returned. # Create Memory Source: https://docs.omi.me/api-reference/memories/create-memory /api-reference/openapi.json post /v1/dev/user/memories Create a new memory for the authenticated user. - **content**: The content of the memory (1-500 characters) - **category**: Memory category (auto-categorized if not provided) - **visibility**: Visibility: public or private (default: private) - **tags**: List of tags associated with the memory A memory is identified by its text. Sending text the user already has (ignoring surrounding whitespace; case-sensitive) returns that memory unchanged, so retries are safe without extra headers. Use PATCH to change an existing memory's fields. After a delete, the same text creates a new memory. # Delete Memory Source: https://docs.omi.me/api-reference/memories/delete-memory /api-reference/openapi.json delete /v1/dev/user/memories/{memory_id} Delete a memory by ID. - **memory_id**: The ID of the memory to delete # Get Memories Source: https://docs.omi.me/api-reference/memories/get-memories /api-reference/openapi.json get /v1/dev/user/memories # Update Memory Source: https://docs.omi.me/api-reference/memories/update-memory /api-reference/openapi.json patch /v1/dev/user/memories/{memory_id} Update a memory's content, visibility, tags, or category. - **memory_id**: The ID of the memory to update - **content**: New content for the memory (optional) - **visibility**: New visibility: public or private (optional) - **tags**: New tags for the memory (optional) - **category**: New category for the memory (optional) # Building the Device Source: https://docs.omi.me/doc/assembly/Build_the_device Step-by-step guide to assemble your own Omi device from parts. ## Before You Start Make sure you have all required components Download and print the case STL files If you don't have access to a 3D printer, check [Makerspace.com](https://makerspace.com/) for printing locations near you, or use an online 3D printing service. *** ## Assembly Instructions Gather all your parts: XIAO board, battery, switch, wires, and 3D printed case. All components laid out Cut the black wire approximately **2/3 inch (17mm)** from the base of the battery connector. Cutting the black wire Remove a small portion of insulation from both ends of the cut wire using a wire stripper. Use the **28 AWG** notch on your wire stripper for best results. Stripped wire ends Follow the soldering diagram to connect the battery to the board. The switch goes in-line with the black (ground) wire. Soldering diagram Be careful with soldering! Use proper ventilation and safety equipment. Insert the switch securely into the battery connector circuit. Switch secured Carefully place the battery and board into the 3D-printed case. Components in case Insert the switch into the notch next to the USB-C slot. Switch in notch Twist the longer red wire gently to help organize it within the case. Twisted wire Carefully curl the twisted wire and place it to the side to ensure it fits within the case. Curled wire placement Align the lid with the case using the ridges as a guide and snap it into place. Attaching the lid Apply even pressure around the edges to ensure the seams snap securely into place. Secured case *** ## Charging Instructions **Important:** Omi can only charge when it is powered **ON**. The device will not charge if powered off. * Use a standard USB-C cable to charge * The LED will indicate charging status * A full charge takes approximately 1-2 hours *** ## Congratulations! You now have a fully assembled Omi device! Install the latest firmware on your device Download and configure the Omi app Having issues? Get help from our community or contact support Get help from the community on Discord # Parts List Source: https://docs.omi.me/doc/assembly/Buying_Guide Everything you need to build your own Omi device. Availability and prices may vary by region. ## Required Components Seeed Studio XIAO nRF52840 Sense Rechargeable LiPo battery Slider switch for power control 3D printed enclosure *** ## Parts List ### Seeed Studio XIAO nRF52840 Sense Board The brain of your Omi device - a compact Bluetooth LE board with built-in microphone. | Region | Store | Price | | - | - | - | | Global | [Seeed Studio](https://www.seeedstudio.com/Seeed-XIAO-BLE-Sense-nRF52840-p-5253.html) | \$15 | | US | [Amazon US](https://amzn.to/3TZD1pO) | \$24 | | EU | [Amazon EU](https://amzn.eu/d/3eG6gaA) | Varies | | India | [Robu.in](https://robu.in/product/seeed-studio-xiao-nrf52840-sense-tinyml-tensorflow-lite-imu-microphone-bluetooth5-0/) | Varies | The Seeed Studio direct store offers the best price at \$15/unit. *** ### Rechargeable Battery A small LiPo battery to power your device. | Region | Store | Price | | - | - | - | | US | [Amazon US](https://amzn.to/3TXlE9f) | \$7 | *** ### Slider Switch Power switch to turn your device on/off. Model: **SS12D00-G3, 3mm** | Region | Store | Price | | - | - | - | | US | [Amazon US](https://www.amazon.com/dp/B099MRCDG8) | \$8 for 30+ units | | EU | [Amazon EU](https://www.amazon.de/dp/B09TVFF6KW) | Varies | | UK | [Amazon UK](https://www.amazon.co.uk/dp/B09TVFF6KW) | Varies | You only need one switch per device. The packs include many extras. *** ### Wires Thin wires for connecting components. | Region | Store | Price | | - | - | - | | US | [Amazon US](https://www.amazon.com/dp/B09X4629C1) | Varies | *** ### 3D Printed Case The enclosure for your Omi device. Get the 3D print files from GitHub Options for getting your case printed: * **Local makerspaces** - Check [Makerspace.com](https://makerspace.com/) for locations near you * **Online services** - Use services like Shapeways, Craftcloud, or PCBWay * **Local libraries** - Many public libraries now have 3D printers available * **University labs** - Students may have access to campus maker labs * **Material**: PLA or PETG recommended * **Layer height**: 0.2mm for good detail * **Infill**: 20% is sufficient * **Supports**: May be needed depending on orientation *** ## Important Notes The provided links are to third-party vendors. We do not guarantee product availability or quality. * Pricing is approximate and may vary by location and shipping fees * Some components may have long shipping times from certain vendors * Consider buying extras of small components like switches *** ## Next Steps Step-by-step assembly instructions Install firmware on your device Set up the Omi app # Build Your Own Omi Device Source: https://docs.omi.me/doc/assembly/introduction As an open-source community, we empower enthusiasts to create their own Omi devices. This guide focuses on building the DevKit 1, as later versions use custom PCBs not suited for DIY assembly. ## Overview Building your own Omi device is a rewarding experience that gives you complete control over your hardware. This guide covers everything you need to know to build the **DevKit 1**. All designs are freely available Customize your build as needed Gain hands-on electronics skills Get help from fellow builders *** ## Is This Guide for You? Building your own Omi device requires **advanced knowledge** of soldering and basic electronics. If you're new to electronics, consider purchasing a pre-built device instead. | Skill Level | Recommendation | | - | - | | Beginner | Purchase from [Omi Shop](https://omi.me) | | Intermediate | Follow this guide with extra caution | | Advanced | This guide is perfect for you | *** ## Is It Cheaper? While building your own device is a great learning experience, it may not always be cheaper than purchasing from our [Shop](https://omi.me). Consider these factors before deciding: Component prices vary by region Multiple vendors mean multiple shipping fees You may need to purchase tools Assembly takes several hours Compare the total cost of parts, tools, and shipping against the shop price before deciding to build your own. *** ## Requirements ### Skills Needed Through-hole and surface-mount experience Basic PCB and circuit understanding Familiarity with programming boards ### Tools & Materials | Tool | Purpose | | - | - | | Soldering iron | Connecting components | | Solder | Joining connections | | Fine-tip tweezers | Handling small parts | | Wire stripper | Preparing wires | | 3D printed case | Device enclosure | *** ## Important Notes **Safety First:** Always follow safety precautions when working with electronics and soldering equipment. Work in a well-ventilated area and wear appropriate protective equipment. **Custom PCBs:** The DevKit 2 and Omi CV1 use custom PCBs, making them unsuitable for DIY assembly without specialized manufacturing equipment. This guide focuses on DevKit 1 only. *** ## Ready to Build? Review and purchase all components from the parts list 3D print or order the enclosure Follow the step-by-step build guide Install the latest firmware *** ## Next Steps See all required components and where to buy them Step-by-step assembly instructions Install firmware on your device Purchase a ready-made device instead # App Setup Source: https://docs.omi.me/doc/developer/AppSetup Set up the Omi Flutter app for development. Build automatically against the local backend harness, or manually with your own. ## Overview There are two ways to set up the Omi app for development: **Recommended for most developers** One command setup against the local backend harness **For custom backends** Full control over configuration and backend Don't want to build from source? Download the official app from the [App Store](https://apps.apple.com/us/app/friend-ai-wearable/id6502156163) or [Google Play](https://play.google.com/store/apps/details?id=com.friend.ios). *** ## Prerequisites Before starting, make sure you have the following installed: Includes Dart - the core framework Required for iOS development Required for Android development iOS dependency manager You'll also need [NDK](https://developer.android.com/ndk/downloads) to build Opus for ARM devices. The local backend harness additionally needs **Python 3.11** (not 3.12+ — the backend pins 3.11), a **Java runtime** for the Firestore emulator, and **firebase-tools** (or `npx`). `make dev-up` names any of these that are missing. *** ## Build the App Automatically This is the **recommended** way to get started. `setup.sh` builds the `dev` flavor against the **local backend harness** — the Python API on port `8000` and the Firebase Auth emulator on port `9099`, using the `demo-omi-local` Firebase project. iOS builds address them as `127.0.0.1`; Android builds default to the emulator's host alias `10.0.2.2`. `setup.sh` does **not** start the backend or the emulator — start the harness first (step 1 below), or the app builds and launches but every request fails to connect. Do not point this build at `https://api.omiapi.com/`. That API verifies Firebase ID tokens against Omi's production Firebase project, and Firebase tokens are project-scoped, so a `demo-omi-local` token is rejected with **401 Unauthorized** on every call — sign-in appears to succeed and nothing else works. Production data requires the explicit `beta` profile (see [Mobile beta](https://github.com/BasedHardware/omi/blob/main/app/README.md#mobile-beta--dogfood)). ### Video Walkthrough