Skip to content
Back to skills

Openwhispr Api

ASecurity

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.

  • 9,078 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added May 27, 2026
data-aibashapi

Works with

  • claude code
  • cursor
  • api
  • mcp

Security analysis

A100/100

Scanned May 27, 2026

npx -y skills add OpenWhispr/openwhispr --skill openwhispr-api --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Openwhispr Api?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Openwhispr Api
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/openwhispr-openwhispr-api/badge)](https://www.skillsdirectory.com/skills/openwhispr-openwhispr-api)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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.
---

# OpenWhispr API v1

Use this reference when making requests to the OpenWhispr REST API. All endpoints are under the V1 path and require API key authentication.

## 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.

### Scopes

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. |

## Base URL

```
https://api.openwhispr.com/api/v1
```

## Response Envelope

Wrap all responses in a consistent envelope.

**Single resource:**
```json
{ "data": { "id": "uuid", "title": "My note", ... } }
```

**Paginated list:**
```json
{
  "data": [{ ... }, { ... }],
  "has_more": true,
  "next_cursor": "2026-04-15T10:30:00.000Z"
}
```

**Error:**
```json
{ "error": { "code": "not_found", "message": "Note not found" } }
```

### Error Codes

| 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 |

## Rate Limits

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) |

## 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.

```
GET /notes/list?limit=50&cursor=2026-04-15T10:30:00.000Z
```

## Endpoints

### Notes

**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.

### Folders

**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.

### Transcriptions

**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`.

### Usage

**Get Usage** — `GET /usage`
Scope: `usage:read`. Returns:
- `words_used` — Words consumed this period
- `words_remaining` — Words left in quota
- `limit` — Total word quota
- `plan` — Current plan (`free`, `pro`, `business`)
- `is_subscribed` — Whether user has active subscription
- `current_period_end` — End of current billing period
- `billing_interval` — Billing cycle

## MCP Server

For 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 Code
```bash
claude mcp add openwhispr --transport http https://mcp.openwhispr.com/mcp \
  --header "Authorization: Bearer owk_live_YOUR_KEY"
```

### Cursor / VS Code
```json
{
  "mcpServers": {
    "openwhispr": {
      "url": "https://mcp.openwhispr.com/mcp",
      "headers": { "Authorization": "Bearer owk_live_YOUR_KEY" }
    }
  }
}
```

## Examples

### List recent notes
```bash
curl -H "Authorization: Bearer owk_live_YOUR_KEY" \
  "https://api.openwhispr.com/api/v1/notes/list?limit=10"
```

### Create a note in a folder
```bash
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
```

### Search notes
```bash
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
```

### Paginate through all notes
```bash
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
```

### Check usage
```bash
curl -H "Authorization: Bearer owk_live_YOUR_KEY" \
  https://api.openwhispr.com/api/v1/usage
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.