Skip to main content
Your agent can show a Rive file during a call: a character, a quiz, a game or a chart. The person’s phone draws it whenever no video from your agent is arriving, and your agent changes it live through Rive data binding.

Before you start

Show and drive the file

1

Put the file on your Contact Card

Upload the .riv with the Attachments API, the same way as a profile photo. Then set it with the upload’s id. The names select what the phone draws; leave one out to use the file’s default.
The card, your agent’s chat handles and the Call object then carry rive.file, the URL where Relay hosts the file, so the phone loads it while the call rings. Send {"rive": {"file": "<that URL>", "artboard": "Quiz"}} to change only the names, or "rive": null to remove the file.
2

Open the rive channel in the call

After connect(), open the channel. Every later call returns the same handle.
If Relay cannot open the channel, rive() fails with the code media_unavailable, and the call goes on.
The person’s client must send {"type":"rive"} on its call-room socket to opt into receiving. The agent sends the same frame to publish. Use the person’s connected socket and pc from the call room.Once the agent publishes, Relay may send an offer with track: "rive" to establish the SCTP transport. Answer it like any other offer; Relay then sends a rive frame with the channel id. Add these cases to your existing serialized room-frame handler:
Person-side WebRTC
After a restart onto a new Session, Relay sends a new id. Open the channel again with that id on the current peer connection.
3

Change the file and hear the person

set writes View Model properties by name or path, trigger fires a trigger, and show switches to another Relay-hosted file with optional starting values. The phone sends back what the person changes.
Python uses the same names: rive.set({...}), rive.trigger("wave"), rive.on("view_model", handler).
4

Time changes to your agent's speech

writeAudio resolves with where that audio starts on your agent’s audio track, in milliseconds. Pass that time plus an offset inside the audio as at, and the phone applies the change when that sample plays. Audio held until the person can hear it gets its real start too.
visemesFromAlignment turns character timings into Preston Blair’s ten mouth shapes, from 0 (rest) to 9 (W and Q), for a viseme number in your file. In Python, write_audio returns the start once the person receives your agent’s audio, and None before that.

Let your framework drive the mouth

Messages

Each message is JSON of at most 1 KB. The channel is unordered and does not resend, so a lost message is gone. A set replaces only the properties it names: a later value for the same property corrects a lost one, and nothing resends a lost trigger. After a media restart the transport opens the channel again and resends the last show and the latest value of every property.

Next steps