Skip to content

Make it possible to retry the video recording if it fails - #168

Merged
zachm-vapi merged 1 commit into
mainfrom
zachm/vapics-1170-missing-videorecordingurl
Aug 20, 2026
Merged

Make it possible to retry the video recording if it fails#168
zachm-vapi merged 1 commit into
mainfrom
zachm/vapics-1170-missing-videorecordingurl

Conversation

@zachm-vapi

@zachm-vapi zachm-vapi commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Linear: VAPICS-1170

When call.startRecording() is called, the client must become ready within 25 seconds, or Daily will time out. If the client fails to become ready (e.g. due to a slow connection), Daily will emit a recording-error event, and the call will not be recorded.

This commit exposes public startRecording() and stopRecording() methods so that the developer can choose to retry the recording if it fails for whatever reason.

For example:

vapi.on('recording-error', (e) => {
  console.error('Recording failed', e);
  // Retry after a short delay
  setTimeout(() => vapi.startRecording(), 5000);
});

@zachm-vapi
zachm-vapi requested a review from kyle-vapi August 7, 2026 17:04

@kyle-vapi kyle-vapi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

zachm-vapi commented Aug 14, 2026

Copy link
Copy Markdown
Contributor Author

@zachm-vapi
zachm-vapi force-pushed the zachm/vapics-1170-missing-videorecordingurl branch from aca20ad to 5213a79 Compare August 20, 2026 21:49

zachm-vapi commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Merge activity

  • Aug 20, 9:51 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Aug 20, 9:51 PM UTC: @zachm-vapi merged this pull request with Graphite.

@zachm-vapi
zachm-vapi merged commit 1780921 into main Aug 20, 2026
5 checks passed
@zachm-vapi
zachm-vapi deleted the zachm/vapics-1170-missing-videorecordingurl branch August 20, 2026 21:51
zachm-vapi added a commit that referenced this pull request Aug 20, 2026
# Use meeting token to start video recording automatically

Linear: VAPICS-1216

## Context

Customers with weak network connections sometimes end calls with no `videoRecordingUrl` because the client-initiated `startRecording()` request never reaches Daily. Per Daily support's recommendation, the backend now creates a meeting token with `start_cloud_recording: true` when video recording is enabled and returns it on the web call as `call.transport.callToken`. Joining with that token makes Daily start the cloud recording automatically, which is more reliable.

This relates to #168, which allows the client to retry the recording if it fails. Both changes are needed, because the recording can still fail even when started via a token.

## Changes

**SDK (`vapi.ts`)**
- `start()` reads `call.transport.callToken` from the create-web-call response and joins the Daily room with it. When a token is present, the client-side `startRecording()` call is skipped because it will start automatically.
- `reconnect()` does the same; the `WebCall` param type gains an optional `transport.callToken` field, which is picked up automatically by apps that pass back the `Call` object from `start()`.
- The `recording-started` listener that sends the `say-first-message` control is now registered *before* `join()` in both methods. On the token path the recording can start while join is still in flight, and a listener registered after join could miss the event (and never trigger the assistant's greeting).
- The `video-recording-setup` progress event reports `metadata.action: 'auto-started-via-meeting-token'` on the token path so the two flows are distinguishable in telemetry.

**Example app** — Updated so that we can test the video recording and reconnect workflows. Video recording is now toggleable via a checkbox, a local camera preview (with recording indicator) shows when the camera is live, the stored call data includes `transport` so reconnects use the token, and Stop (leave) / End are now separate buttons (previously the stop button would always end the call, so it wasn't possible to reconnect).

## Backward compatibility

- **No token (old servers, ZDR orgs, token-creation failure):** `join()` gets no `token` key and the SDK falls back to client-initiated `startRecording()` — identical to the old flow.
- **Old SDKs + new server:** ignore the token field and keep client-initiated recording; the backend still sets room-level `enable_recording` for exactly this case.
- **Recording stop semantics are unchanged.** The recording is still stopped manually when the client leaves because the meeting token only *starts* it automatically.
- **Progress-event ordering:** on the token path, the `video-recording-started` progress event can occasionally be emitted before `video-recording-setup: completed`, because the recording may start while `join()` is still in flight (on the old client-initiated path, setup always preceded started). Consumers should not assume the ordering; each event carries a timestamp and, on the token path, a `metadata.action` discriminator for disambiguation.

## Testing

Used the example app to manually verify that video recording works, including when the caller stops and reconnects to the call. Tested against both the Vapi prod server (before the backend change), and my local test server (including the backend change), to verify that we still fall back to the old behavior when a `callToken` isn't provided.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants