docs: Add Mintlify tabs navigation and OpenAPI-powered API Reference#5998
Conversation
- Restructure docs.json to use Mintlify tabs: Documentation, API Reference, Build Apps, Hardware, MCP - Add icons to all tabs and groups - Create OpenAPI 3.1.0 spec for the Omi Developer API (replaces plant store placeholder) - Add 19 interactive API endpoint pages using Mintlify OpenAPI integration - Cover all endpoints: Memories, Conversations, Action Items, API Keys - Include proper schemas, examples, auth config, and error responses - Keep existing hand-written API guide pages alongside interactive playground pages
|
Preview deployment for your docs. Learn more about Mintlify Previews.
|
Greptile SummaryThis PR upgrades the Omi developer docs from a flat sidebar with a placeholder plant-store OpenAPI spec to a clean 5-tab Mintlify navigation (Documentation, API Reference, Build Apps, Hardware, MCP) backed by a proper OpenAPI 3.1.0 spec covering memories, conversations, action items, and API keys. All 19 new interactive endpoint pages are thin MDX stubs that delegate to the spec, which is the correct Mintlify pattern. Existing hand-written guide pages are preserved and co-located with the new playground pages. Key findings:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
User([Developer]) -->|Bearer Token| API[api.omi.me]
API --> MEM["/v1/dev/user/memories\nGET · POST · PATCH · DELETE"]
API --> CONV["/v1/dev/user/conversations\nGET · POST · PATCH · DELETE · GET id"]
API --> SEGS["/v1/dev/user/conversations/from-segments\nPOST"]
API --> ACT["/v1/dev/user/action-items\nGET · POST · PATCH · DELETE"]
API --> KEYS["/v1/dev/keys\nGET · POST · DELETE"]
API --> GOALS["/v1/dev/user/goals\n⚠️ Not in OpenAPI spec"]
MEM -->|batch| MEMBATCH["/v1/dev/user/memories/batch\nPOST"]
ACT -->|batch| ACTBATCH["/v1/dev/user/action-items/batch\nPOST"]
CONV --> AI{{AI Pipeline\nDiscard · Structure · Memories · Apps}}
SEGS --> AI
style GOALS fill:#ffcccc,stroke:#cc0000
Reviews (1): Last reviewed commit: "Add Mintlify tabs navigation and OpenAPI..." | Re-trigger Greptile |
Top-level headings (Get Started, Core Development, etc.) no longer have icons. Nested sub-groups (Backend, Firmware, SDK, Audio & Testing) keep their icons. Individual page icons remain via frontmatter.
| ## 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 | ||
| X-RateLimit-Limit: 100 | ||
| X-RateLimit-Remaining: 95 | ||
| X-RateLimit-Reset: 1642694400 | ||
| ``` | ||
|
|
||
| ## Resources | ||
|
|
||
| <CardGroup cols={2}> |
There was a problem hiding this comment.
Rate limit headers are not implemented in the Developer API
The documentation states "Rate limit headers are included in every response" and lists X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers — but the backend developer.py router does not implement these headers for any of the developer API endpoints. Rate-limiting headers only exist in the notification/integration routes (routers/integration.py, routers/notifications.py).
Publishing these headers as a guarantee will cause confusion when developers instrument their clients expecting them and find they are absent. Either the rate-limit section should be removed/marked as "coming soon", or the backend needs to be updated to actually emit these headers.
| ## 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 | |
| X-RateLimit-Limit: 100 | |
| X-RateLimit-Remaining: 95 | |
| X-RateLimit-Reset: 1642694400 | |
| ``` | |
| ## Resources | |
| <CardGroup cols={2}> | |
| ## Rate Limits | |
| Requests are rate-limited per API key. If you exceed the limit you will receive a `429 Too Many Requests` response. | |
| > **Note:** Rate-limit response headers are not currently returned by the API. |
| }, | ||
| "ApiKeyCreated": { | ||
| "type": "object", | ||
| "properties": { | ||
| "id": { "type": "string" }, | ||
| "name": { "type": "string" }, | ||
| "key_prefix": { "type": "string" }, | ||
| "key": { "type": "string", "description": "The full API key. **Only returned once during creation.**" }, | ||
| "created_at": { "type": "string", "format": "date-time" }, | ||
| "last_used_at": { "type": ["string", "null"], "format": "date-time" } | ||
| } | ||
| }, | ||
| "CreateApiKey": { |
There was a problem hiding this comment.
CreateApiKey schema omits the scopes field
The actual DevApiKeyCreate Pydantic model (and the DevApiKey / DevApiKeyCreated response models) all include an optional scopes: List[str] field that lets callers limit a key's permissions. The OpenAPI spec defines CreateApiKey with only name, so:
- Users cannot create scoped keys through the interactive playground.
- The
ApiKeylist response silently drops anyscopesthat already exist on returned keys.
Suggested addition to the schema:
"CreateApiKey": {
"type": "object",
"required": ["name"],
"properties": {
"name": { "type": "string", "description": "Descriptive name for the key." },
"scopes": {
"type": "array",
"items": { "type": "string" },
"description": "Optional permission scopes. Defaults to read-only if omitted."
}
}
}The same scopes field should be added to the ApiKey and ApiKeyCreated response schemas.
| "description": { "type": "string", "description": "The action item text." }, | ||
| "completed": { "type": "boolean", "description": "Whether completed." }, | ||
| "created_at": { "type": "string", "format": "date-time" }, | ||
| "updated_at": { "type": "string", "format": "date-time" }, | ||
| "due_at": { "type": ["string", "null"], "format": "date-time", "description": "Due date (null if not set)." }, | ||
| "completed_at": { "type": ["string", "null"], "format": "date-time", "description": "When completed (null if pending)." }, | ||
| "conversation_id": { "type": ["string", "null"], "description": "Associated conversation ID." } | ||
| } | ||
| }, | ||
| "CreateActionItem": { | ||
| "type": "object", | ||
| "required": ["description"], | ||
| "properties": { | ||
| "description": { "type": "string", "minLength": 1, "maxLength": 500, "description": "The action item description." }, | ||
| "completed": { "type": "boolean", "default": false, "description": "Whether completed." }, | ||
| "due_at": { "type": "string", "format": "date-time", "description": "Due date in ISO 8601 format." } |
There was a problem hiding this comment.
Memory category enum is narrower than the backend accepts
The CreateMemory schema documents only ["interesting", "system", "manual"], but the MemoryCategory enum in backend/models/memories.py still accepts core, hobbies, lifestyle, interests, habits, work, skills, learnings, other, and auto (legacy values). If a user sends one of those legacy values, the API accepts it and maps it internally, but the playground will flag it as invalid.
A short note in the description would prevent confusion:
| "description": { "type": "string", "description": "The action item text." }, | |
| "completed": { "type": "boolean", "description": "Whether completed." }, | |
| "created_at": { "type": "string", "format": "date-time" }, | |
| "updated_at": { "type": "string", "format": "date-time" }, | |
| "due_at": { "type": ["string", "null"], "format": "date-time", "description": "Due date (null if not set)." }, | |
| "completed_at": { "type": ["string", "null"], "format": "date-time", "description": "When completed (null if pending)." }, | |
| "conversation_id": { "type": ["string", "null"], "description": "Associated conversation ID." } | |
| } | |
| }, | |
| "CreateActionItem": { | |
| "type": "object", | |
| "required": ["description"], | |
| "properties": { | |
| "description": { "type": "string", "minLength": 1, "maxLength": 500, "description": "The action item description." }, | |
| "completed": { "type": "boolean", "default": false, "description": "Whether completed." }, | |
| "due_at": { "type": "string", "format": "date-time", "description": "Due date in ISO 8601 format." } | |
| "category": { "type": "string", "enum": ["interesting", "system", "manual"], "description": "Memory category. Legacy values (core, hobbies, work, etc.) are still accepted for backward compatibility but are not recommended for new integrations." }, |
| "schema": { "type": "integer", "default": 0 } | ||
| }, | ||
| { | ||
| "name": "start_date", | ||
| "in": "query", | ||
| "description": "Filter by start date (inclusive). ISO 8601 format.", | ||
| "schema": { "type": "string", "format": "date-time" } | ||
| }, | ||
| { | ||
| "name": "end_date", | ||
| "in": "query", |
There was a problem hiding this comment.
Goals API endpoints are absent from the spec
The backend developer.py router exposes a complete Goals API (GET/POST /v1/dev/user/goals, GET/PATCH/DELETE /v1/dev/user/goals/{goal_id}, PATCH /v1/dev/user/goals/{goal_id}/progress, GET /v1/dev/user/goals/{goal_id}/history). None of these endpoints appear in the new OpenAPI spec, so developers have no interactive playground access to goals and may not discover the feature at all.
If the Goals API is intentionally unpublished (e.g. still in beta), a comment in the spec or a note in the introduction page explaining this would help avoid confusion.
…asedHardware#5998) ## What Restructure the Omi docs to use **Mintlify tabs** for top-level navigation and add a professional **OpenAPI-powered API Reference** with interactive playground. ## Changes ### Navigation Tabs - Reorganized `docs.json` from flat groups into 5 tabs: **Documentation**, **API Reference**, **Build Apps**, **Hardware**, **MCP** - Added icons to all tabs and sidebar groups - All existing pages preserved — just reorganized into a cleaner hierarchy ### API Reference (OpenAPI) - Created a proper **OpenAPI 3.1.0 spec** (`api-reference/openapi.json`) covering all Developer API endpoints - Replaces the placeholder plant store spec - Accurate schemas, parameters, request/response examples based on the actual backend routers - Bearer auth configuration for the API playground - Added **19 interactive endpoint pages** using Mintlify OpenAPI integration: - Memories: list, create, create-batch, update, delete - Conversations: list, create, create-from-segments, get, update, delete - Action Items: list, create, create-batch, update, delete - API Keys: list, create, revoke - Existing hand-written API guide pages (with code examples, use cases) kept alongside the interactive playground pages ### Before / After - **Before**: Single flat sidebar with all groups visible. API reference was just hand-written guides. OpenAPI spec was a placeholder plant store. - **After**: Clean tabbed navigation. API Reference tab has both guides AND interactive OpenAPI playground. Users can try endpoints directly from the docs. ## Testing - All existing page paths preserved (no broken links) - OpenAPI spec validates against 3.1.0 - Follows Mintlify docs.json tabs format
What
Restructure the Omi docs to use Mintlify tabs for top-level navigation and add a professional OpenAPI-powered API Reference with interactive playground.
Changes
Navigation Tabs
docs.jsonfrom flat groups into 5 tabs: Documentation, API Reference, Build Apps, Hardware, MCPAPI Reference (OpenAPI)
api-reference/openapi.json) covering all Developer API endpointsBefore / After
Testing