Desktop SDK (Beta)

🚧

API under construction

This document refers to API endpoints which are not publicly listed in our API specification. We are working on this and they will be added soon. You can assume the examples below will work and the API's will updated with backwards-compatibility in mind.

The Desktop SDK allows for recording Zoom calls locally on Apple Silicon Macs.

The lifecycle of a Desktop SDK recording is as follows:

  1. The Desktop SDK notifies your code that a Zoom meeting has started locally.
  2. Your code makes a request to your backend for an upload token.
  3. Your backend creates a new Desktop SDK Upload using the Recall.ai API, and returns the upload token to your desktop application.
  4. Your desktop code calls startRecording with the upload token.
  5. Wait for the sdk_upload.completed webhook
  6. Run async transcription (optional)
  7. Download the recording video and transcription

That's it! Once the call finishes, a recording will be created on the Recall API and your backend will be notified via webhook.

Installation

npm install @recallai/desktop-sdk

Usage

init(config)

RecallAiSdk.init({
  api_url: "http://us-east-1.recall.ai"
});

Initialize the Desktop SDK. This should be called once at startup. Specify the api_url for your region.

addEventListener(eventType, listener)

RecallAiSdk.addEventListener("meeting-detected", async (evt) => {
  const {window: {id: id}} = evt;
});

RecallAiSdk.addEventListener("sdk-state-change", async (evt) => {
  const {sdk: {state: { code: code }}} = evt;
  // code is either "recording" or "idle"
});

Install an event listener for eventType events. eventType can be one of:

  • meeting-detected: Triggered when a Zoom meeting is found, either when a new one starts, or after the SDK initializes and there is a meeting already in progress.
  • sdk-state-change: Triggered when the in-progress recording changes state, either to "idle" to indicate that recording is over, or "recording" to indicate that a recording is in progress.

startRecording({windowId, uploadToken})

RecallAiSdk.startRecording({
  windowId: ...,
  uploadToken: ...
});

Begin recording. This function is usually called inside an event listener for meeting-detected. windowId is provided by the meeting-detected callback, and uploadToken is acquired by creating an SDK Upload on your backend.

Creating an SDK upload

Endpoint

curl --request POST \
     --url https://us-east-1.recall.ai/api/v1/sdk-upload/ \
     --header 'Authorization: Token your-recall-api-token' \
     --header 'content-type: application/json' \
     --data '{ "artifacts": { "video_mixed_mp4": {} } }'

Response

{
   "id": "4abf29fc-36b5-4853-9f84-a9990b9e354b",
   "upload_token": "96472e47-a78c-4774-a9a2-93afad7d398d"
}

Example

An example demonstrating how to use these functions together could be:

RecallAiSdk.init({
  api_url: "http://us-east-1.recall.ai"
});

RecallSdk.addEventListener('meeting-detected', async (evt) => {
  const res = await Backend.fetch(`/api/create_sdk_recording`, AppState.client_token);
  const payload = await res.json();
	
  await RecallSdk.startRecording({
    windowId: evt.window.id,
    uploadToken: res.upload_token
  });
});

RecallSdk.addEventListener('sdk-state-change', async (evt) => {
  switch (event.sdk.state.code) {
    case 'recording':
      console.log("Recording started");
      break;
    case 'idle':
      console.log("Recording stopped");
      break;
  }
});

Webhooks

At points in the lifecycle of a Desktop SDK Upload, you will receive webhook notifications about the state of the upload.

sdk_upload.completed

This webhook is sent when an SDK Upload has finished successfully.

{
  "data": {
    "sdk_upload": {
      "created_at": "2024-10-18T15:12:01.032224Z",
      "id": "6a98c97a-3e6e-4acd-8684-0b2ddeeb8281",
      "recording_id": "71f4d556-4c8c-4627-a253-61344e8f22f7",,
      "status": {
        "code": "complete"
      }
    }
  },
  "event": "sdk_upload.completed"
}

sdk_upload.failed

This webhook is sent when an SDK Upload has finished unsuccessfully.

{
  "data": {
    "sdk_upload": {
      "created_at": "2024-10-18T15:12:01.032224Z",
      "id": "6a98c97a-3e6e-4acd-8684-0b2ddeeb8281",
      "recording_id": null,
      "status": {
        "code": "failed"
      }
    }
  },
  "event": "sdk_upload.failed"
}

Running transcription

After receiving the sdk_upload.completed webhook you can retrieve the recorded video file using create transcript artifact endpoint with the recording_id field from the webhook:

Endpoint

curl --request POST \
     --url https://us-east-1.recall.ai/api/v1/recording/71f4d556-4c8c-4627-a253-61344e8f22f7/create_transcript \
     --header 'Authorization: Token your-recall-api-token' \
     --header 'content-type: application/json' \
     --data '{
        "provider": {
            "assembly_ai_async": {
                "language_code": "en",
                "speaker_labels": True,
                "diarization": True
            }
        },
        "diarization": {
            "algorithm_priority": ["speaker_timeline"]
        }
    }'

Response

{
  "id": "642a12e1-c542-4c27-80be-ea67f41d3196,
  "status": {
    "code": "processing"
  }
}

Retrieve the recording & transcript

After receiving the sdk-upload.completed webhook you can retrieve the recorded video file using retrieve recording endpoint with the recording_id field from the webhook:

Endpoint

curl --request GET \
     --url https://us-east-1.recall.ai/api/v1/recording/71f4d556-4c8c-4627-a253-61344e8f22f7 \
     --header 'Authorization: Token your-recall-api-token' \
     --header 'content-type: application/json' 

Response

{
  "id": "71f4d556-4c8c-4627-a253-61344e8f22f7",
  "shortcuts": {
    "video_mixed": {
      "status": {
        "code": "done"
      },
      "data": {
        "download_url": "https://some-download-endpoint",
      }
    },
    "transcript": {
      "status": {
        "code": "done"
      },
      "data": {
        "download_url": "https://some-download-endpoint",
      }
    }
  }
}