obsidian-local-rest-api
Obsidian Local REST API - Reference
Source: https://github.com/coddingtonbear/obsidian-local-rest-api
Full OpenAPI Spec: obsidian-local-rest-api-openapi.yaml
Authentication
All endpoints (except GET /) require Bearer token authentication:
Authorization: Bearer <your-api-key>
Find the API key in Obsidian Settings > Plugins > Local REST API.
Base URL
- HTTPS:
https://127.0.0.1:27124(self-signed cert) - HTTP:
http://127.0.0.1:27123
The plugin generates a self-signed certificate on first run. The cert can be fetched from /obsidian-local-rest-api.crt.
Endpoints
System
| Method | Path | Description |
|---|---|---|
| GET | / |
Server status & auth check (no auth required) |
| GET | /obsidian-local-rest-api.crt |
Returns the TLS certificate |
| GET | /openapi.yaml |
Returns OpenAPI spec |
GET / response:
{
"authenticated": true,
"ok": "OK",
"service": "Obsidian Local REST API",
"versions": { "obsidian": "...", "self": "..." }
}
Vault File Operations (/vault/{filename})
| Method | Path | Description |
|---|---|---|
| GET | /vault/{filename} |
Read file content |
| PUT | /vault/{filename} |
Create or overwrite file |
| POST | /vault/{filename} |
Append content to file |
| PATCH | /vault/{filename} |
Partially update content (heading/block/frontmatter targeting) |
| DELETE | /vault/{filename} |
Delete file |
| GET | /vault/ |
List files in vault root |
| GET | /vault/{dirpath}/ |
List files in directory (trailing slash = directory) |
GET (read file):
- Default
Accept: returns raw markdown (text/markdown) Accept: application/vnd.olrapi.note+json: returns JSON with parsed frontmatter, tags, statsAccept: application/vnd.olrapi.document-map+json: returns headings, block refs, frontmatter fields
NoteJson schema:
{
"content": "string (markdown)",
"frontmatter": {},
"path": "string",
"stat": { "ctime": 0, "mtime": 0, "size": 0 },
"tags": ["string"]
}
GET (directory listing):
- Returns
{"files": [{"path": "…", "stat": {…}}]}
PUT (create/overwrite):
- Body: file content
Content-Type: text/markdownfor notesIf-None-Match: *header: only create if file doesn't exist (returns 412 if it does)
POST (append):
- Body: content to append
Content-Type: text/markdown- Content is appended to end of file
DELETE:
- Returns 204 on success, 404 if not found
PATCH Operations (Surgical Edits)
The PATCH method enables targeted content modifications within a note.
Required Headers:
| Header | Values | Description |
|---|---|---|
Operation |
append, prepend, replace |
What to do |
Target-Type |
heading, block, frontmatter |
What kind of target |
Target |
string | The specific target (heading path, block ref ID, frontmatter field name) |
Optional Headers:
| Header | Default | Description |
|---|---|---|
Target-Delimiter |
:: |
Separator for nested headings (e.g., Heading 1::Subheading) |
Trim-Target-Whitespace |
false |
Trim whitespace from target |
Create-Target-If-Missing |
false |
Create the target if it doesn't exist |
Examples:
Append under a heading:
PATCH /vault/path/to/note.md
Operation: append
Target-Type: heading
Target: Heading 1::Subheading 1:1:1
Content-Type: text/markdown
Hello
Replace a frontmatter field:
PATCH /vault/path/to/note.md
Operation: replace
Target-Type: frontmatter
Target: status
Content-Type: application/json
"done"
Append to block reference:
PATCH /vault/path/to/note.md
Operation: append
Target-Type: block
Target: 2d9b4a
Content-Type: text/markdown
New content here
Active File Operations (/active/)
Same methods as vault files (GET, PUT, POST, PATCH, DELETE) but operates on the currently open file in Obsidian. No {filename} parameter needed.
Periodic Notes (/periodic/{period}/)
| Method | Path | Description |
|---|---|---|
| GET/PUT/POST/PATCH/DELETE | /periodic/{period}/ |
Current period's note |
| GET/PUT/POST/PATCH/DELETE | /periodic/{period}/{year}/{month}/{day}/ |
Specific date's note |
{period} values: daily, weekly, monthly, quarterly, yearly
Same request/response semantics as vault file operations.
Search
Simple Search:
POST /search/simple/?query=search+terms
Returns matching filenames with context snippets.
Response:
[
{
"filename": "path/to/note.md",
"score": 0.95,
"matches": [{ "match": { "start": 0, "end": 10 }, "context": "..." }]
}
]
Structured Search:
POST /search/
Content-Type: application/vnd.olrapi.dataview.dql+txt
TABLE file.name, file.mtime FROM "folder" WHERE contains(tags, "#coffee")
Or with JsonLogic:
POST /search/
Content-Type: application/vnd.olrapi.jsonlogic+json
{"and": [{"glob": [{"var": "path"}, "daily/*"]}]}
Commands
| Method | Path | Description |
|---|---|---|
| GET | /commands/ |
List all available commands |
| POST | /commands/{commandId}/ |
Execute a command |
GET /commands/ response:
{
"commands": [
{ "id": "global-search:open", "name": "Search: Search in all files" },
{ "id": "graph:open", "name": "Graph view: Open graph view" }
]
}
Tags
| Method | Path | Description |
|---|---|---|
| GET | /tags/ |
List all tags with usage counts |
Open File in Obsidian UI
POST /open/{filename}?newLeaf=true
Opens the specified file in Obsidian's interface. Creates the file if it doesn't exist.
Error Responses
All errors return:
{
"errorCode": 40149,
"message": "A brief description of the error."
}
Error codes are 5-digit numbers unique to each error type.
Key Endpoints for Pour
Based on the project spec, these are the most relevant endpoints:
GET /- Check if API is available (connectivity test)PUT /vault/{filename}- Create new notes (coffee logs, music sets)PATCH /vault/{filename}- Append under headers (journal entries)GET /vault/{dirpath}/- List files in directory (populate dynamic dropdowns)POST /search/- Dataview queries for dynamic selects by tag