Open Morse

Reference

Vault

14 routes, generated from Morse’s own OpenAPI document. Every path below hangs off the base URL, and every one needs the bearer header.

The examples are built from each route’s schema, so the shapes and types are exactly what the API declares. The values are illustrative, and no one has run them.

Your vault: your own entries and the shared ones.

GET/vault

Says whether each has a secret, never what it is. 423 until the PIN has been entered.

GET/vault

curl "$MORSE/vault" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
[
  {
    "can_manage": true,
    "has_secret": true,
    "id": "3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60",
    "label": "…",
    "notes": "…",
    "shared": true,
    "updated_at": "2026-10-02T10:30:00+05:30",
    "url": "https://onmorse.com/priya",
    "username": "…"
  }
]

Add a vault entry, such as a login, link or password, private or shared.

POST/vault

POST/vault

curl -X POST "$MORSE/vault" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "label": "…" }'
201
{
  "can_manage": true,
  "has_secret": true,
  "id": "3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60",
  "label": "…",
  "notes": "…",
  "shared": true,
  "updated_at": "2026-10-02T10:30:00+05:30",
  "url": "https://onmorse.com/priya",
  "username": "…"
}

Give this session's five minutes back, before they run out.

POST/vault/lock

Another session keeps its own.

POST/vault/lock

curl -X POST "$MORSE/vault/lock" \
  -H "Authorization: Bearer $MORSE_TOKEN"

Whether this member has a vault PIN and whether it is currently open.

GET/vault/pin

What the page asks before it draws anything.

GET/vault/pin

curl "$MORSE/vault/pin" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "factor": "app",
  "has_pin": true,
  "locked_out_until": "…",
  "seconds_left": 1,
  "unlocked": true
}

Set or change the vault PIN.

PUT/vault/pin

Changing one needs the current one, so a session left open cannot replace the second factor with one its finder knows.

PUT/vault/pin

curl -X PUT "$MORSE/vault/pin" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "pin": "…" }'

Forget the vault PIN, so the vault answers again and the page offers to set a new one. The way back from a forgotten PIN.

DELETE/vault/pin

Needs a token from /api/auth/reauth/* minted for this same user in the last five minutes, sent as X-Morse-Recent-Auth — the same proof a hard voice-note delete takes. Behind a fresh sign-in rather than behind the PIN, because the PIN is the thing that has been forgotten. Unlike that delete, an API token is **not** proof here: a token is a standing credential, and one that could drop the vault's second factor would be a way round it rather than a way back.

DELETE/vault/pin

curl -X DELETE "$MORSE/vault/pin" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "x-morse-recent-auth: …"

Whether this member has an authenticator app set up, and how many recovery codes they have left.

GET/vault/totp

GET/vault/totp

curl "$MORSE/vault/totp" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "enrolled": true,
  "pending": true,
  "recovery_codes_left": 1
}

Make a secret for an app to scan. Nothing is gated by it until a code from the app comes back to /totp/confirm — beginning must not be able to lock someone out of their own vault.

POST/vault/totp

Behind the gate that is already there. Without that, the laptop left open in a meeting room — the case the PIN exists for — could enrol its own app over the owner's PIN, which both opens the vault for the intruder and stops the owner's PIN working, since the app replaces it. Replacing a factor must be at least as hard as using one. With no factor set up yet require_open returns straight away, so a first enrolment is unchanged.

POST/vault/totp

curl -X POST "$MORSE/vault/totp" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "secret": "…",
  "uri": "…"
}

Turn the authenticator app off.

DELETE/vault/totp

Behind the same fresh sign-in as forgetting a PIN: turning the second factor off must take more than an open session, or it is not a second factor.

DELETE/vault/totp

curl -X DELETE "$MORSE/vault/totp" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "x-morse-recent-auth: …"

Finish setting up the app, and hand back the recovery codes. This is the only time they can be read.

POST/vault/totp/confirm

Behind the existing gate as well as /totp: confirming is the half that actually changes which factor the vault asks for.

POST/vault/totp/confirm

curl -X POST "$MORSE/vault/totp/confirm" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "code": "4KJ9P2" }'
200
{
  "recovery_codes": [
    "…"
  ]
}

Open the vault for five minutes.

POST/vault/unlock

Wrong PINs are counted and then held off.

POST/vault/unlock

curl -X POST "$MORSE/vault/unlock" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "pin": "…" }'
200
{
  "seconds": 1
}

Change a vault entry.

PUT/vault/{entry_id}

Anyone may edit a shared one; only its creator may make it private.

PUT/vault/{entry_id}

curl -X PUT "$MORSE/vault/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "label": "…" }'
200
{
  "can_manage": true,
  "has_secret": true,
  "id": "3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60",
  "label": "…",
  "notes": "…",
  "shared": true,
  "updated_at": "2026-10-02T10:30:00+05:30",
  "url": "https://onmorse.com/priya",
  "username": "…"
}

Delete a vault entry: your own, or a shared one you created.

DELETE/vault/{entry_id}

DELETE/vault/{entry_id}

curl -X DELETE "$MORSE/vault/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60" \
  -H "Authorization: Bearer $MORSE_TOKEN"

Decrypt one entry's secret and return it.

POST/vault/{entry_id}/reveal

Logged, and never cached.

POST/vault/{entry_id}/reveal

curl -X POST "$MORSE/vault/3f9c1a24-5e6f-4b31-9a77-1b2c3d4e5f60/reveal" \
  -H "Authorization: Bearer $MORSE_TOKEN"
200
{
  "secret": "…"
}