Message UI
Try it
Change the loading text and color, then switch to a deployed or error result. Click the info icon to inspect deployment details. Open popovers stay open as live message updates arrive. The JSON below follows your preview.
{
"agent": "Deploy Bot",
"text": "Deploying API to production…\nEnvironment: production/api\nBranch: main\nService: https://api.fryll.com\nJob logs: https://gitlab.com/fryll/fryll/-/pipelines",
"children": [
{
"type": "loading",
"label": "Deploying API…",
"color": "#7d97ff"
},
{
"type": "info",
"label": "Deployment details",
"children": [
{
"type": "text",
"text": "Environment: production/api\nBranch: main\nService: https://api.fryll.com\nJob logs: https://gitlab.com/fryll/fryll/-/pipelines"
}
]
}
]
}Three small components
children is an ordered array of components. Text and loading appear in order. An info component adds a small ⓘ beside the preceding component; its text children appear in a popover.
{
"type": "text",
"text": "API deployment · production"
}text is required. Newlines are preserved; Markdown and HTML are displayed as literal text.
{
"type": "loading",
"label": "Thinking…",
"color": "#7D97FF"
}label is required, up to 200 characters. Use it for “Thinking…”, “Reading logs…” or any progress description. Optional color accepts a six-digit hex value such as #7D97FF and colors the indicator. The label keeps the client’s readable text color. Omit the color to use the app accent.
{
"type": "info",
"label": "Deployment details",
"children": [
{
"type": "text",
"text": "Branch: main\nEnvironment: production"
}
]
}Info keeps metadata and links behind a small, always-visible icon. Click or tap to open; click outside or press Escape to close. The required label names the button for assistive technology and becomes the popover heading. Its children must be nonempty text components; HTTP(S) links remain clickable. Nested info and loading inside info are not supported.
Keep info at the same position when updating a message to preserve an open popover. Put it immediately after the status it describes. An info component at the beginning gets its own row. Include relevant details in the plain-text fallback for search and older clients.
Send a live message
Use your existingconversation token. Send JSON with a plain-text fallback and optional children. Plain-text and form requests keep working as before.
curl --fail-with-body "https://api.fryll.com/in/$FRYLL_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"agent":"Deploy Bot","text":"Deploying API…","children":[{"type":"text","text":"API deployment · production"},{"type":"loading","label":"Building image…","color":"#7D97FF"}]}'The response includes the messageid,children andloading_expires_at. Keep the ID for updates. The top-leveltext supplies search text, notification previews and a fallback for older clients.
Update the same message
Replace its children as the task advances. Remove the loading component when work succeeds or fails, and update the fallback at the same time.
curl --fail-with-body -X PATCH "https://api.fryll.com/in/$FRYLL_TOKEN/messages/$MESSAGE_ID" \
-H 'Content-Type: application/json' \
-d '{"text":"API deployed successfully","children":[{"type":"text","text":"✅ API deployed successfully"}]}'On an error, replace the result with useful failure text. A PATCH changes the existing message and reaches clients through realtime updates; it does not send a new-message notification.
Omit a field to leave it unchanged. Sendingchildren replaces the full array. Sendchildren: [] to clear the UI and display the fallback again. PATCH may update children alone. The sender and thread cannot be changed.
Authenticated clients can also send children through the existing channel and conversation message POST/PATCH endpoints. Those endpoints usebody_text for the fallback and keep their existing author permissions.
Behavior and limits
- Up to 32 components, including info children, with at most 40,000 combined text/label characters including info content. The fallback is also limited to 40,000 characters.
- Labels are limited to 200 characters. Unknown types/properties, invalid colors, empty info children and non-text children inside info return a 400 response.
- Loading expires 30 minutes after creation or the last children update. Clients stop animating and show “status update expired”; expiry does not imply success or failure. A text-only update does not renew it.
- Posting and updating each allow 60 requests per minute per token. Update meaningful milestones rather than every animation frame.
- Desktop, iOS and Android render the components with their own controls. Unsupported component types fall back to the message text.