mirror of
https://github.com/OpenWhispr/openwhispr.git
synced 2026-10-02 05:04:47 +08:00
feat: update agent skill with spaces context
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: openwhispr-api
|
||||
description: Use this skill when building integrations with the OpenWhispr REST API, calling OpenWhispr endpoints, managing notes/folders/transcriptions programmatically, or connecting to the OpenWhispr MCP server. Covers authentication, all V1 endpoints, pagination, rate limits, error handling, and the remote MCP server.
|
||||
description: Use this skill when building integrations with the OpenWhispr REST API, calling OpenWhispr endpoints, managing notes/folders/transcriptions programmatically, accessing team-space content with workspace keys, or connecting to the OpenWhispr MCP server. Covers authentication, all V1 endpoints, spaces, pagination, rate limits, error handling, and the remote MCP server.
|
||||
---
|
||||
|
||||
# OpenWhispr API v1
|
||||
@@ -15,12 +15,19 @@ Pass the API key as a Bearer token in the `Authorization` header on every reques
|
||||
Authorization: Bearer owk_live_YOUR_KEY
|
||||
```
|
||||
|
||||
Generate keys from the OpenWhispr desktop app under **Settings > API Keys**. Keys start with `owk_live_` and are shown once at creation.
|
||||
There are two kinds of key:
|
||||
|
||||
- **Personal keys** (`owk_live_`) — access your own private notes, folders, and transcriptions. Generated under **Settings > API Keys**.
|
||||
- **Workspace keys** (`ow_wks_live_`) — access a workspace's **team spaces**. Generated by a workspace admin under **Settings > Workspace > Developer**.
|
||||
|
||||
Both are shown once at creation.
|
||||
|
||||
### Scopes
|
||||
|
||||
Each key has scoped permissions. The API rejects requests missing the required scope with `403 Forbidden`.
|
||||
|
||||
**Personal key scopes:**
|
||||
|
||||
| Scope | Grants |
|
||||
| --------------------- | ------------------------------------------------- |
|
||||
| `notes:read` | List, get, and search notes. List folders. |
|
||||
@@ -28,6 +35,28 @@ Each key has scoped permissions. The API rejects requests missing the required s
|
||||
| `transcriptions:read` | List and get transcriptions. |
|
||||
| `usage:read` | Read usage statistics. |
|
||||
|
||||
**Workspace key scopes:**
|
||||
|
||||
| Scope | Grants |
|
||||
| ------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| `workspace:notes:read` | List, get, and search team-space notes. |
|
||||
| `workspace:notes:write` | Create, update, and delete team-space notes. |
|
||||
| `workspace:folders:read` | List team-space folders. |
|
||||
| `workspace:folders:write` | Create team-space folders. |
|
||||
| `workspace:transcriptions:read` | Space discovery only for now — no transcription endpoints accept workspace keys yet. |
|
||||
| `workspace:*` | All of the above (admin). |
|
||||
|
||||
Any of the content scopes above also grants `GET /spaces/list` (space discovery).
|
||||
|
||||
### Team spaces
|
||||
|
||||
A **space** is a shared container of notes and folders inside a workspace. Personal keys never see team-space content; **workspace keys** do, and always address one space at a time via a `space_id`:
|
||||
|
||||
- Discover the spaces a key can reach with `GET /spaces/list`.
|
||||
- `list`, `create`, and `search` for notes and folders **require** a `space_id` (query param or body field) when called with a workspace key, and reject one when called with a personal key.
|
||||
- Operations addressed by note id (`GET/PATCH/DELETE /notes/{id}`, `GET /notes/{id}/transcript`) resolve the note's space automatically — no `space_id` needed. A workspace key may act on any note in any of its workspace's spaces.
|
||||
- `space_id` cannot be changed through the API — a note stays in the space it was created in. Move notes between spaces from the desktop app.
|
||||
|
||||
## Base URL
|
||||
|
||||
```
|
||||
@@ -50,7 +79,7 @@ Wrap all responses in a consistent envelope.
|
||||
{
|
||||
"data": [{ ... }, { ... }],
|
||||
"has_more": true,
|
||||
"next_cursor": "2026-04-15T10:30:00.000Z"
|
||||
"next_cursor": "opaque-cursor-string"
|
||||
}
|
||||
```
|
||||
|
||||
@@ -94,14 +123,19 @@ Response headers on every request:
|
||||
|
||||
## Pagination
|
||||
|
||||
List endpoints use cursor-based pagination. Pass the `next_cursor` value from a previous response as the `cursor` query parameter to fetch the next page. When `has_more` is `false`, there are no more results.
|
||||
List endpoints use cursor-based pagination. Treat `next_cursor` as an **opaque string**: pass it back verbatim as the `cursor` query parameter to fetch the next page — never parse it. (Notes cursors are base64url-encoded composites; transcription cursors are timestamps. Timestamp cursors issued before the composite format remain accepted.) When `has_more` is `false`, there are no more results. An unparseable cursor returns `400 validation_error`.
|
||||
|
||||
```
|
||||
GET /notes/list?limit=50&cursor=2026-04-15T10:30:00.000Z
|
||||
GET /notes/list?limit=50&cursor=NEXT_CURSOR_FROM_PREVIOUS_RESPONSE
|
||||
```
|
||||
|
||||
## Endpoints
|
||||
|
||||
### Spaces (workspace keys only)
|
||||
|
||||
**List Spaces** — `GET /spaces/list`
|
||||
Scope: any workspace content scope (`workspace:notes:read/write`, `workspace:folders:read/write`, or `workspace:transcriptions:read`). Returns the non-archived team spaces in the key's workspace (`id`, `name`, `slug`, `description`, `emoji`, `created_at`, `updated_at`). Use a returned `id` as the `space_id` on notes/folders requests.
|
||||
|
||||
### Notes
|
||||
|
||||
**List Notes** — `GET /notes/list`
|
||||
@@ -110,10 +144,11 @@ GET /notes/list?limit=50&cursor=2026-04-15T10:30:00.000Z
|
||||
| `limit` | integer | No | 1-100, default 50 |
|
||||
| `cursor` | string | No | Pagination cursor |
|
||||
| `folder_id` | UUID | No | Filter by folder |
|
||||
Scope: `notes:read`
|
||||
| `space_id` | UUID | Workspace keys | Team space to list. Required for workspace keys; rejected for personal keys. |
|
||||
Scope: `notes:read` (personal) / `workspace:notes:read` (workspace)
|
||||
|
||||
**Get Note** — `GET /notes/{id}`
|
||||
Scope: `notes:read`. Returns 404 if the note does not exist or is deleted.
|
||||
Scope: `notes:read` / `workspace:notes:read`. Returns 404 if the note does not exist or is deleted. A workspace key may fetch any note in its workspace's spaces.
|
||||
|
||||
**Create Note** — `POST /notes/create`
|
||||
| Field | Type | Required | Description |
|
||||
@@ -123,7 +158,8 @@ Scope: `notes:read`. Returns 404 if the note does not exist or is deleted.
|
||||
| `enhanced_content` | string | No | Cleaned/enhanced version |
|
||||
| `note_type` | enum | No | `personal` (default), `meeting`, `upload` |
|
||||
| `folder_id` | UUID | No | Target folder |
|
||||
Scope: `notes:write`. Returns `201` with the created note.
|
||||
| `space_id` | UUID | Workspace keys | Team space to create in. Required for workspace keys; rejected for personal keys. |
|
||||
Scope: `notes:write` / `workspace:notes:write`. Returns `201` with the created note.
|
||||
|
||||
**Update Note** — `PATCH /notes/{id}`
|
||||
| Field | Type | Required | Description |
|
||||
@@ -132,29 +168,34 @@ Scope: `notes:write`. Returns `201` with the created note.
|
||||
| `content` | string | No | New content |
|
||||
| `enhanced_content` | string | No | New enhanced content |
|
||||
| `folder_id` | UUID | No | Move to folder |
|
||||
Scope: `notes:write`. All fields optional — only provided fields are updated.
|
||||
Scope: `notes:write` / `workspace:notes:write`. All fields optional — only provided fields are updated. Cannot change a note's space.
|
||||
|
||||
**Delete Note** — `DELETE /notes/{id}`
|
||||
Scope: `notes:write`. Soft-deletes the note. Returns `204 No Content`.
|
||||
Scope: `notes:write` / `workspace:notes:write`. Soft-deletes the note. Returns `204 No Content`.
|
||||
|
||||
**Search Notes** — `POST /notes/search`
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `query` | string | Yes | Search text (1-500 chars) |
|
||||
| `limit` | integer | No | 1-50, default 20 |
|
||||
Scope: `notes:read`. Uses hybrid semantic (vector) + full-text search with relevance scoring. Costs 5x against rate limit.
|
||||
| `space_id` | UUID | Workspace keys | Team space to search. Required for workspace keys; rejected for personal keys. |
|
||||
Scope: `notes:read` / `workspace:notes:read`. Uses hybrid semantic (vector) + full-text search with relevance scoring. Costs 5x against rate limit.
|
||||
|
||||
### Folders
|
||||
|
||||
**List Folders** — `GET /folders/list`
|
||||
Scope: `notes:read`. Returns all folders sorted by `sort_order` then `created_at`.
|
||||
| Param | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `space_id` | UUID | Workspace keys | Team space to list. Required for workspace keys; rejected for personal keys. |
|
||||
Scope: `notes:read` / `workspace:folders:read`. Returns all folders sorted by `sort_order` then `created_at`.
|
||||
|
||||
**Create Folder** — `POST /folders/create`
|
||||
| Field | Type | Required | Description |
|
||||
|-------|------|----------|-------------|
|
||||
| `name` | string | Yes | Folder name (1-100 chars) |
|
||||
| `sort_order` | integer | No | Sort position |
|
||||
Scope: `notes:write`. Max 50 folders per user. Returns `409` if name already exists.
|
||||
| `space_id` | UUID | Workspace keys | Team space to create in. Required for workspace keys; rejected for personal keys. |
|
||||
Scope: `notes:write` / `workspace:folders:write`. Max 50 folders per user. Returns `409` if name already exists.
|
||||
|
||||
### Transcriptions
|
||||
|
||||
@@ -260,3 +301,22 @@ done
|
||||
curl -H "Authorization: Bearer owk_live_YOUR_KEY" \
|
||||
https://api.openwhispr.com/api/v1/usage
|
||||
```
|
||||
|
||||
### Work with team spaces (workspace key)
|
||||
|
||||
```bash
|
||||
# 1. Discover the spaces this workspace key can reach
|
||||
curl -H "Authorization: Bearer ow_wks_live_YOUR_KEY" \
|
||||
https://api.openwhispr.com/api/v1/spaces/list
|
||||
|
||||
# 2. List notes in a space (space_id is required for workspace keys)
|
||||
curl -H "Authorization: Bearer ow_wks_live_YOUR_KEY" \
|
||||
"https://api.openwhispr.com/api/v1/notes/list?space_id=SPACE_UUID&limit=50"
|
||||
|
||||
# 3. Create a note in that space
|
||||
curl -X POST \
|
||||
-H "Authorization: Bearer ow_wks_live_YOUR_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"content": "Kickoff notes", "title": "Kickoff", "space_id": "SPACE_UUID"}' \
|
||||
https://api.openwhispr.com/api/v1/notes/create
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user