Skip to content

Media (A2) ​

Photos, voice notes, videos, documents, and avatars are uploaded directly to storage with a pre-signed URL. The API never receives file bytes.

Upload flow ​

App                              API                         Storage
 │ POST /media/uploads             │                             │
 │────────────────────────────────▶│                             │
 │ 201 {mediaId, uploadUrl, …}     │                             │
 │◀────────────────────────────────│                             │
 │ PUT uploadUrl (file bytes, uploadHeaders)                     │
 │──────────────────────────────────────────────────────────────▶│
 │ 200                                                           │
 │◀──────────────────────────────────────────────────────────────│
 │ POST /media/{mediaId}/complete  │                             │
 │────────────────────────────────▶│ verify size, make thumbnail │
 │ 200 Media {status: "ready"}     │                             │
 │◀────────────────────────────────│                             │
 │ message.send {type:"image", mediaId}  (or PATCH /me {avatarMediaId})

POST /media/uploads ​

json
{ "purpose": "message", "mimeType": "image/jpeg", "sizeBytes": 482113, "fileName": "IMG_2041.jpg" }

purpose: message or avatar.

Response 201:

json
{
  "mediaId": "01JH…",
  "uploadUrl": "https://storage.chatter.maragato.ca/…&X-Amz-Signature=…",
  "uploadMethod": "PUT",
  "uploadHeaders": { "Content-Type": "image/jpeg" },
  "expiresAt": "2026-10-22T14:35:11.482Z"
}

Upload with exactly the method and headers given. The URL expires after 15 minutes.

POST /media/{mediaId}/complete ​

Call after the upload succeeds. Returns Media. status is pending while the thumbnail is generated (usually under 2 seconds) and ready after. You can send the message while pending.

GET /media/{mediaId} ​

Returns Media. Allowed for the owner and for members of a conversation that contains it.

Media object ​

json
{
  "id": "01JH…",
  "mimeType": "image/jpeg",
  "sizeBytes": 482113,
  "width": 1280,
  "height": 960,
  "durationMs": null,
  "url": "https://cdn.chatter.maragato.ca/m/01JH…?sig=…",
  "thumbnailUrl": "https://cdn.chatter.maragato.ca/t/01JH…?sig=…",
  "status": "ready"
}
  • url and thumbnailUrl are signed and expire after 1 hour. Cache files locally by id, not by URL. If a download returns 403, call GET /media/{id} for fresh URLs.
  • thumbnailUrl is a JPEG, max 320 px, for images and videos. null for audio and documents.
  • durationMs is set for audio and video.

Limits and types ​

KindMIME typesMax size
Imageimage/jpeg, image/png, image/heic, image/webp16 MB
Audioaudio/m4a, audio/mp4, audio/aac, audio/mpeg16 MB
Videovideo/mp4, video/quicktime64 MB
Documentapplication/pdf100 MB
Avatarimage/jpeg, image/png, image/heic5 MB

Other types fail with 400 VALIDATION_FAILED. Too large: 413 PAYLOAD_TOO_LARGE.

Tips: compress photos to JPEG ~0.7 quality, max 2048 px on the long side. Record voice notes as AAC in .m4a. Show upload progress with URLSession upload tasks.

Questions? Reply to your invitation email.