createTicket and sendMessage,
in both directions (the user sends; agent-sent media renders in the thread).
Limits
How upload works
The SDK runs a two-phase upload so bytes go straight to storage, never through the ClarioDesk API:1
Sign
The SDK requests a presigned upload target for each file.
2
Normalize & upload
Images are normalized to JPEG client-side (this strips HEIC/EXIF and caps
dimensions). The SDK then PUTs the bytes directly to Cloudflare R2, or to
Cloudflare Stream for video, which transcodes to universal H.264 and
produces a free poster frame.
3
Bind
On message send, the SDK binds the uploaded ids to the message.
Message.attachments then carries the rendered payloads.Progress
Each upload exposes per-tile progress so you can render a progress ring:Sending
MediaPicker / ImageNormalizer via
init({ attachments: { picker, normalizer } }), or build and upload
OutgoingAttachments yourself.
Reading
Presigned GET URLs expire. If an image fails to load because its URL aged out, re-presign it:Video playback is external in v1 on Flutter and React Native. An in-app HLS
player would ship a heavy native dependency to every host, so video uses
external/system playback there. The Swift SDK plays video in-app via
AVPlayer (free and native on iOS). The in-app image viewer is a
lightweight, zero-dependency zoomable view on all three.iOS permission strings
The native media picker requires usage strings in your iOS app’sInfo.plist:
NSPhotoLibraryUsageDescription, NSCameraUsageDescription, and
NSMicrophoneUsageDescription (for video). The React Native Expo config plugin
can add these for you. See the RN installation guide.