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.
PUTthe 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 }'{
"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 -X PUT "URL_FROM_STEP_1" \
-H "Content-Type: image/jpeg" \
--data-binary @me.jpg3 · 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
| What | 1 · Ask | 3 · Confirm |
|---|---|---|
| Profile photo | POST /users/me/avatar/upload | POST /users/me/avatar/complete |
| Knowledge file | POST /knowledge/uploads | POST /knowledge/uploads/complete |
| Voice-note audio | POST /voice-notes/{id}/audio | POST /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.