agent-skills/openwhispr-api/SKILL.md
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.
npx skillsauth add OpenWhispr/openwhispr openwhispr-apiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use this reference when making requests to the OpenWhispr REST API. All endpoints are under the V1 path and require API key authentication.
Pass the API key as a Bearer token in the Authorization header on every request.
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.
Each key has scoped permissions. The API rejects requests missing the required scope with 403 Forbidden.
| Scope | Grants |
|-------|--------|
| notes:read | List, get, and search notes. List folders. |
| notes:write | Create, update, and delete notes. Create folders. |
| transcriptions:read | List and get transcriptions. |
| usage:read | Read usage statistics. |
https://api.openwhispr.com/api/v1
Wrap all responses in a consistent envelope.
Single resource:
{ "data": { "id": "uuid", "title": "My note", ... } }
Paginated list:
{
"data": [{ ... }, { ... }],
"has_more": true,
"next_cursor": "2026-04-15T10:30:00.000Z"
}
Error:
{ "error": { "code": "not_found", "message": "Note not found" } }
| HTTP Status | Code | Meaning |
|-------------|------|---------|
| 400 | validation_error | Invalid request body or query params |
| 401 | invalid_api_key | Missing, malformed, expired, or revoked key |
| 403 | forbidden | Key lacks required scope |
| 404 | not_found | Resource does not exist or belongs to another user |
| 405 | method_not_allowed | Wrong HTTP method |
| 409 | conflict | Duplicate resource (e.g. folder name) |
| 429 | rate_limited | Rate limit exceeded — check Retry-After header |
| 500 | internal_error | Server error |
Enforced per API key with minute and daily windows. Search requests cost 5x against the rate limit.
| Plan | Per Minute | Per Day | |------|-----------|---------| | Free | 30 | 1,000 | | Pro | 120 | 10,000 | | Business | 300 | 50,000 |
Response headers on every request:
| Header | Description |
|--------|-------------|
| X-RateLimit-Limit | Max requests per minute |
| X-RateLimit-Remaining | Remaining in current window |
| X-RateLimit-Reset | Unix timestamp when window resets |
| Retry-After | Seconds to wait (only on 429) |
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.
GET /notes/list?limit=50&cursor=2026-04-15T10:30:00.000Z
List Notes — GET /notes/list
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| limit | integer | No | 1-100, default 50 |
| cursor | string | No | Pagination cursor |
| folder_id | UUID | No | Filter by folder |
Scope: notes:read
Get Note — GET /notes/{id}
Scope: notes:read. Returns 404 if the note does not exist or is deleted.
Create Note — POST /notes/create
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| content | string | Yes | Note body text |
| title | string | No | Note title |
| 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.
Update Note — PATCH /notes/{id}
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| title | string | No | New title |
| 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.
Delete Note — DELETE /notes/{id}
Scope: 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.
List Folders — GET /folders/list
Scope: notes: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.
List Transcriptions — GET /transcriptions/list
| Param | Type | Required | Description |
|-------|------|----------|-------------|
| limit | integer | No | 1-100, default 50 |
| cursor | string | No | Pagination cursor |
Scope: transcriptions:read. Returns transcription history with text, word_count, source, provider, model, language, audio_duration_ms, processing_ms.
Get Transcription — GET /transcriptions/{id}
Scope: transcriptions:read.
Get Usage — GET /usage
Scope: usage:read. Returns:
words_used — Words consumed this periodwords_remaining — Words left in quotalimit — Total word quotaplan — Current plan (free, pro, business)is_subscribed — Whether user has active subscriptioncurrent_period_end — End of current billing periodbilling_interval — Billing cycleFor AI assistant integration (Claude, Cursor, VS Code), connect to the remote MCP server at:
https://mcp.openwhispr.com/mcp
Pass the API key via Authorization: Bearer header. All V1 endpoints are available as MCP tools. The server uses Streamable HTTP transport (stateless, no sessions).
claude mcp add openwhispr --transport http https://mcp.openwhispr.com/mcp \
--header "Authorization: Bearer owk_live_YOUR_KEY"
{
"mcpServers": {
"openwhispr": {
"url": "https://mcp.openwhispr.com/mcp",
"headers": { "Authorization": "Bearer owk_live_YOUR_KEY" }
}
}
}
curl -H "Authorization: Bearer owk_live_YOUR_KEY" \
"https://api.openwhispr.com/api/v1/notes/list?limit=10"
curl -X POST \
-H "Authorization: Bearer owk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Remember to review PR #42", "title": "TODO", "folder_id": "UUID"}' \
https://api.openwhispr.com/api/v1/notes/create
curl -X POST \
-H "Authorization: Bearer owk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "quarterly budget discussion"}' \
https://api.openwhispr.com/api/v1/notes/search
cursor=""
while true; do
response=$(curl -s -H "Authorization: Bearer owk_live_YOUR_KEY" \
"https://api.openwhispr.com/api/v1/notes/list?limit=100&cursor=${cursor}")
echo "$response" | jq '.data[]'
has_more=$(echo "$response" | jq -r '.has_more')
[ "$has_more" != "true" ] && break
cursor=$(echo "$response" | jq -r '.next_cursor')
done
curl -H "Authorization: Bearer owk_live_YOUR_KEY" \
https://api.openwhispr.com/api/v1/usage
tools
Use this skill whenever the user wants to operate on OpenWhispr notes, folders, transcriptions, or audio from a terminal or shell. The OpenWhispr CLI (`openwhispr` binary, npm package `@openwhispr/cli`) talks to either the local desktop app or the cloud API and exposes every operation needed for managing notes, folders, transcriptions, audio, plus auth and config. Trigger this skill when the user mentions "openwhispr cli", running shell commands against OpenWhispr, automating note workflows, cleaning up a transcription, building agent integrations against OpenWhispr, or scripting any OpenWhispr operation — even if they don't say "CLI" explicitly.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------