Assets
In the portal: Settings, then Assets.
What it is
An asset is one file you have uploaded: a picture, a video, a sound recording or a document. They live in one library for your tenancy, and content points at them by reference rather than carrying a copy.
The library stores two facts about a file that matter to you. What kind of file it is, which is read out of the file itself rather than typed in. And whether it is public or private, which decides which store it goes into and cannot be changed afterwards.
Everything a participant can see is public. Private covers a participant's own material, such as a profile picture or something they sent in a chat, and none of it can be used as content.
What it looks like
An asset reaches a participant in three places, and it looks different in each.
- As a cover picture on a home item. Set on the sequence, and shown on the item's card. Where the picture sits inside the card and what shape it is cropped to are decided by the surface, not by the file. See Anatomy of a surface for the positions and the crops.
- As a surface's own picture. A small round image beside the surface heading, 32 pixels across.
- Inside a sequence, through an
assetatom. A picture draws inline and opens full screen when tapped. Audio and video show a row that opens a player.
When you would use one
You upload an asset whenever the content is a file rather than words.
A worked example. A sample tenancy's breathing course has a two minute recorded
practice and a photograph for the course card. The recording is uploaded once and
placed in an asset atom on the practice page. The photograph is uploaded once and
set as the sequence's cover picture, where it appears on the home screen without ever
appearing inside the sequence.
You do not upload a separate copy per journey. One asset can be referenced by any number of atoms, sequences and surfaces.
What you can upload
The file's real type has to be on this list. Anything else is refused with
asset_unsupported_type.
| Kind | Types accepted | Largest file |
|---|---|---|
| Pictures | JPEG, PNG, WebP | 10 MB each |
| Video | MP4, WebM | 200 MB each |
| Audio | MP3, AAC, and the two types an M4A file reports itself as | 50 MB each |
| Documents (for linking to, not for playing inside a sequence) | 25 MB each |
SVG is deliberately not accepted. An SVG file can carry executable code inside it, so it is kept out on purpose rather than by oversight. Export the artwork as PNG or WebP.
The cap is per file and it is per type. A 12 MB photograph is refused even though a 190 MB video is fine, because the ceiling that applies is the one for its own type.
Convert a GIF or a HEIC to PNG, WebP or MP4 before you upload it. The library
takes the types in the table above. The apps will draw a GIF or a HEIC where an
address points at one, so an external address on an asset atom is the other route.
The controls
| Field | What it accepts | Default | Notes |
|---|---|---|---|
name | text | none | What you call it in the library. Never shown to a participant. |
description | text | none | For your own team. |
code | capitals, numbers and underscores, starting with a letter, up to 64 | none | Optional. It is how an import file refers to the asset by a stable name instead of an id. |
visibility | public, private | none, required | Fixed at upload. Only public assets can be used in content. |
status | active, archived | active | Archived assets drop out of the picker. |
Everything else about an asset is measured rather than set: its type, its size in bytes, its checksum, and the width and height of a picture.
Archive rather than delete. Archiving takes a file out of the picker and leaves everything already using it untouched, which is what you want in almost every case.
Check the surfaces and the sequence covers before you delete a file. A delete is
refused with asset_in_use where an atom points at the asset, and it goes through
where a surface or a sequence cover points at it.
How an upload works
Uploading is two steps, and the second one is where the file becomes usable.
- You describe the file, and the platform gives back a one-off address to upload
to. The file goes straight to storage and never travels through the interface. At
this point the asset exists with
uploadStatus: pending, and nothing can load it until the upload is confirmed. - You confirm the upload. The platform reads the bytes back and proves them:
it identifies the real file type from the file's own contents, checks that type
against the list above, checks the size against that type's ceiling, recomputes
the checksum and compares it, and measures a picture's width and height. Only then
does it flip to
readyand mint an address.
The file's real type beats what you said it was. Renaming a document to .png
does not get it in, and it fails at step 2 rather than sitting in the library looking
fine.
Nothing can use an asset until it is ready. A reference to a pending asset is
refused with asset_not_ready, and a reference to a private one with
asset_not_public.
Replacing a file keeps the old one live until the new one is proved. The replacement is uploaded alongside, and only swaps in once it passes the same checks. Participants never see a gap, and a failed replacement changes nothing. The new file lands under a new address, so no cache anywhere can serve the old picture as the new one.
How it renders
Inside a sequence, the file's address decides how it is played, not its stored type. The apps look at the end of the address and the site it points at. An address ending in a picture extension draws inline. One ending in an audio extension gets a Listen row. An address on one of the two video hosting sites the apps recognise opens as an embedded player. Anything else gets a video player.
A document belongs in a content atom, or behind a button atom. Write the
content as a content atom, or host the document where it opens in a browser and
link to it from a button atom. Inside a sequence the address is what decides how a
file plays, and a PDF has no recognised ending, so keep documents to those two
routes.
A picture never reserves space it does not need. An item with no cover picture has no gap where one would go, so a surface mixing items with and without pictures stays tidy.
A cover picture is not shown inside the sequence. It appears on the home item and
nowhere else. If the participant should see the picture while reading, it needs to be
an asset atom as well.
Check that a picture is public and ready before you rely on it. A picture the
apps cannot load draws a placeholder in its place, and the usual cause is a private
asset, or one whose upload never finished.
Say in words what a picture conveys. Put the description in the content atom
beside it, so the meaning is on the screen for everyone.
Put the length of a recording in the sequence description. People decide whether to start something by how long it takes, and the description is where they look.
Worked cases
A course cover photograph. JPEG under 10 MB, public, set as the sequence's
assetId. Crop it to the shape the surface uses before uploading, because the
surface crops to fill and the platform does not letterbox.
A guided audio practice. MP3 or M4A under 50 MB, public, placed in an asset
atom on its own page with a content atom above it saying what the practice is and
how long it takes.
A handout. Write it as a content atom. Or host the document where it opens in
a browser, and link to it from a button atom.
Next
One library, one upload per file, and any number of atoms, sequences and surfaces pointing at it. Uploading is proved rather than trusted: the platform reads the bytes back and checks the real type, the size and the checksum before anything can use the file, and a replacement only swaps in once it has passed the same checks, so participants never see a gap.
Atom types is where a file becomes something on a screen, through
an asset atom.
Anatomy of a surface decides where a cover picture sits on the card and what shape it is cropped to.