Files
Jason Stedwell 2fc3a0a80b ver-0.7
2026-06-19 21:12:14 -05:00

8.6 KiB

ECHO — Obsidian Local REST API Reference

Server: https://echoapi.alwisp.com (reverse proxy → backend Obsidian Local REST API) Auth header: Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab The endpoint has a valid TLS certificate-k is not required. Paths address the vault at its root.

Prefer scripts/echo.sh over the raw recipes below. It wraps every verb with auth, status checking, retry, idempotent append, and frontmatter patches. The recipes here are the underlying mechanics and the fallback. If you call curl directly, check the HTTP status — add -o /dev/null -w "%{http_code}" and branch on it. A PATCH to a non-existent heading returns 400 invalid-target (errorCode 40080) and the write is silently lost; a bare curl that ignores status will report success anyway. GET returns 404 for a missing file. Treat any >= 400 as a failed operation, surface it, and do not continue as if it succeeded.


Reading Files

# Read any file by vault path
curl -s \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  "https://echoapi.alwisp.com/vault/_agent/context/current-context.md"

Returns raw file content (text/markdown). On 404, the file does not exist.

# Read a specific heading's content only
curl -s \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md/heading/Operator"

Nested headings: separate levels with :: (URL-encode spaces as %20):

/vault/path/to/note.md/heading/Work%3A%3AMeetings

Listing Directories

# List contents of a directory (trailing slash required)
curl -s \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  "https://echoapi.alwisp.com/vault/_agent/sessions/"

Returns JSON: { "files": [...], "folders": [...] }.


Appending Content (POST)

POST appends to the end of an existing file. Creates the file if it doesn't exist.

cat > /tmp/obs_entry.md << 'OBSEOF'
- 2026-06-05: your entry here
OBSEOF

curl -s -X POST \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  -H "Content-Type: text/markdown" \
  --data-binary @/tmp/obs_entry.md \
  "https://echoapi.alwisp.com/vault/inbox/captures/inbox.md"

Creating or Overwriting Files (PUT)

PUT creates a new file or fully overwrites an existing one. Intermediate directories are created automatically.

cat > /tmp/obs_file.md << 'OBSEOF'
---
type: session-log
status: complete
created: 2026-06-05
updated: 2026-06-05
tags: [agent, session]
agent_written: true
source_notes: []
---

# content here

## Related
- [[projects/active/some-project]]
OBSEOF

curl -s -X PUT \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  -H "Content-Type: text/markdown" \
  --data-binary @/tmp/obs_file.md \
  "https://echoapi.alwisp.com/vault/_agent/sessions/2026-06-05-1430-my-session.md"

Patching a Specific Section (PATCH)

PATCH edits inside a file without rewriting it. Target and operation are set via headers.

Append under a heading

Heading targets must be the FULL heading path, ::-delimited from the top-level heading. A bare subheading name returns 400 invalid-target (errorCode 40080). Example: ## Fact / Pattern nested under # Operator PreferencesTarget: Operator Preferences::Fact / Pattern. Percent-encode non-ASCII characters (e.g. H%C3%A9llo); spaces are fine.

cat > /tmp/obs_patch.md << 'OBSEOF'
Jason prefers concise status updates — lead with the decision.
OBSEOF

curl -s -X PATCH \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  -H "Operation: append" \
  -H "Target-Type: heading" \
  -H "Target: Operator Preferences::Fact / Pattern" \
  -H "Content-Type: text/markdown" \
  --data-binary @/tmp/obs_patch.md \
  "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md"

Discover heading / block / frontmatter targets

When unsure of the exact heading path, GET the note with the document-map Accept header:

curl -s \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  -H "Accept: application/vnd.olrapi.document-map+json" \
  "https://echoapi.alwisp.com/vault/_agent/memory/semantic/operator-preferences.md"

Returns { "headings": [...], "blocks": [...], "frontmatterFields": [...] }. Copy the heading string verbatim into Target.

Replace a heading's content entirely

Same call with Operation: replace — e.g. to refresh a project's Project Name::Status.

Prepend under a heading

Same call with Operation: prepend.

Patch a frontmatter field

curl -s -X PATCH \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  -H "Operation: replace" \
  -H "Target-Type: frontmatter" \
  -H "Target: updated" \
  -H "Content-Type: application/json" \
  --data '"2026-06-05"' \
  "https://echoapi.alwisp.com/vault/projects/active/vault-foundation.md"

Searching

curl -s -X POST \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  "https://echoapi.alwisp.com/search/simple/?query=weekly+review"

Returns an array of { filename, score, matches: [{ context, match }] }.


Deleting Files

curl -s -X DELETE \
  -H "Authorization: Bearer 241265fbe6830934a9a4ad3e69335f64a42153b663aa5b0017cb1ea1217b2bab" \
  "https://echoapi.alwisp.com/vault/inbox/imports/old-note.md"

Only on explicit operator request. Deletion is destructive.


URL-Encoding Notes

  • Path separators (/) in the vault path are literal — do not encode them.
  • Spaces in filenames or heading targets in a URL: use %20.
  • Nested heading levels in a URL path: use %3A%3A for ::.
  • Heading text in the Target: header: the full heading path joined by :: (e.g. Operator Preferences::Fact / Pattern), no #; spaces are fine; percent-encode non-ASCII.

Memory Routing Map

Situation Vault path Method
Quick capture / unsorted inbox/captures/inbox.md (date-prefixed line) POST
Raw imported material inbox/imports/ PUT
Operator preference / durable fact _agent/memory/semantic/operator-preferences.md PATCH
Other durable facts, patterns _agent/memory/semantic/<slug>.md PUT
Event record (what happened) _agent/memory/episodic/<slug>.md PUT
Short-lived, time-boxed state _agent/memory/working/<slug>.md PUT
Task-scoped context / focus _agent/context/current-context.md PATCH / PUT
Working-session log _agent/sessions/YYYY-MM-DD-HHMM-<slug>.md PUT
Long-running project state projects/<lifecycle>/<slug>.md (lifecycle: incubatingactiveon-hold/archived; folder and status: MUST agree) PUT + PATCH
Ongoing area of responsibility (standing domain, no end state) areas/<domain>/<slug>.md (<domain>: business/personal/learning/systems) PUT
Non-obvious decision (ADR) decisions/by-date/YYYY-MM-DD-<slug>.md (mirror only into an existing project note's ## Key Decisions; otherwise skip) PUT
Person context resources/people/<name>.md PUT / PATCH
Company / organization context resources/companies/<slug>.md PUT / PATCH
Concept / reference note resources/concepts/ or resources/references/ PUT
Meeting notes / call recap resources/meetings/YYYY-MM-DD-<slug>.md PUT
Skill / plugin capability entry (catalog, not build work) _agent/skills/active/<slug>.md (→ archived/ when retired) PUT
Daily activity / Agent Log journal/daily/YYYY-MM-DD.md POST / PATCH
Journal rollup journal/{weekly/YYYY-Www,monthly/YYYY-MM,quarterly/YYYY-Qn,annual/YYYY}.md (weekly = opt-in on first session of a new ISO week; monthly = offered with Vault Health; quarterly/annual = manual) PUT
Vault-health audit (agent self-maintenance) _agent/health/YYYY-MM-vault-health.md (monthly; NOT a journal entry) PUT
Session-end orientation pointer _agent/heartbeat/last-session.md (one line, overwritten each session end) PUT
Bootstrap marker (plugin-owned) _agent/echo-vault.md (schema_version, bootstrap date) — the "is this vault set up?" probe GET / PUT

Slug rules: kebab-case, ASCII, ~40 chars max. Every file carries canonical frontmatter (see vault-layout.md).