Open Morse

Guide

Uploads

Files never pass through Morse’s server. You ask where to put one, send it straight to storage, and then tell Morse it has arrived, which is the moment Morse looks at it.

The shape

Three surfaces take files, and all three work the same way. Learn it once here and the other two are the same call with a different path.

  • Ask. Tell Morse the type and size. You get back a short-lived URL and an upload key.
  • Send. PUT the bytes to that URL, with the content type you declared. Morse is not involved.
  • Confirm. Post the upload key back. Morse fetches the file, checks it, and keeps it.

1 · Ask

POST/users/me/avatar/upload

curl -X POST "$MORSE/users/me/avatar/upload" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "content_type": "image/jpeg", "size": 48213 }'
200 OK
{
  "url": "https://storage.example.com/…?signature=…",
  "content_type": "image/jpeg",
  "upload": "7b2c9e14-0a3d-4f58-9c61-8e5a2d7f0b43"
}

The URL is short-lived. Ask, then send; do not hold one and use it later.

2 · Send

Straight to storage, not to Morse. Nothing here carries your token, because the signature in the URL is the authorisation.

curl
curl -X PUT "URL_FROM_STEP_1" \
  -H "Content-Type: image/jpeg" \
  --data-binary @me.jpg

3 · Confirm

This is the call that does the work: Morse copies the upload, checks the copy, and keeps it. Until you make it, nothing has been added to your account.

POST/users/me/avatar/complete

curl -X POST "$MORSE/users/me/avatar/complete" \
  -H "Authorization: Bearer $MORSE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "upload": "7b2c9e14-0a3d-4f58-9c61-8e5a2d7f0b43" }'

The web app sends a little more at this step: the photo the square was cut from, and where it was cut, so a profile picture can be re-framed later. A script can leave both out.

Where each one lives

What1 · Ask3 · Confirm
Profile photoPOST /users/me/avatar/uploadPOST /users/me/avatar/complete
Knowledge filePOST /knowledge/uploadsPOST /knowledge/uploads/complete
Voice-note audioPOST /voice-notes/{id}/audioPOST /voice-notes/{id}/audio/complete

The differences are small but real. A knowledge file declares file_name, file_type and size, and its confirm call carries the note’s fields (a title, and optionally a folder) because the upload becomes a note. Voice-note audio declares a sha256 as well, so Morse can tell whether what arrived is what you sent.

Before offering a file picker, ask GET /knowledge/uploads: it says whether this server takes files at all, how large, and of which types. PDF, Word, Excel, CSV, text and Markdown are the accepted kinds.

When it goes wrong

  • Give up cleanly. Voice-note audio has POST /voice-notes/{id}/audio/abort, which discards whatever arrived. Use it rather than leaving a half-sent upload behind.
  • A refusal need not cost a transfer. Knowledge checks the note’s own fields before it downloads anything, so a bad title fails immediately.
  • The upload is always deleted. Whether the confirm succeeds or fails, the staged file goes. Only the kept copy survives, and only on success.

Full schemas for all three are under Reference, in the tag each route belongs to.