Voice archiving fundamentals

Understanding voice calls

In the context of the Voice Archiving API, a ‘voice call’ is a voice exchange that occurs on a specific messaging platform, e.g. Global Relay App, Zoom, etc., for capture in Global Relay Archive.

The most common scenarios are calls between users, virtual meetings, and voicemail. The files, or voice records, for these calls can then be attached to EML messages in the Archive.

Understanding the key resources

There are 3 key resources in the Voice Archiving payload you send in an API request:

Call Overview

This consists of metadata about the voice call:

  • *type: Provided to you during enrollment by your Global Relay Implementation engineer, this identifies the data type being archived, e.g. Zoom, Global Relay App, etc.
  • callId: A unique ID for the voice call that can be re-used in subsequent Voice Archiving API requests, so your data displays as a single, sequential conversation in the Archive.
  • owner: User who started the call, meeting, recording, etc., where you can specify their name, phone, company, and email. In Global Relay Archive, the owner displays in the From field of the archived message.
  • callType: Identifies the type of voice call being archived, e.g. intercom, meeting, one-to-one call, etc.
  • direction: Indicates whether the call was inbound or outbound.
  • stopReason: Indicates why the call ended, i.e. owner_hangup, remote_handup, forward, or unknown.
  • deviceName: Identifies the device used to make the call, e.g. office phone.
  "callOverview": {
    "callId": "1234565775",
    "callType": "Zoom",
    "owner": {
      "phone": "555-657-9980",
      "name": "Kate Rydell",
      "email" : "kate.rydell@agimperial.com"
      "company": "AG Imperial",
      "detail": "Owner"
    },
    "deviceName": "office phone",
    "direction": "inbound",
    "stopReason": "owner_hangup",
  },

* Call Type

This field must be included in all requests, and must match the value provided to you by Global Relay when you enroll your application; otherwise, the data you send will not be archived correctly.

Voice Records

These represent the voice calls, meetings, or recordings sent in the request.

Each voiceRecord should include:

  • startTime: Identifies when the call began in epoch, i.e. UTC, time.
  • stopTime: Identifies when the call ended in epoch, i.e. UTC, time.
  • recordingFile: Outlines the name and location of the voice file that was uploaded to the /files endpoint.
  • participants: Identifies who participated in the call. In addition to providing the name, phone, company, and email of the participant, you can also indicate when the participant joined and left the call using the joinTimeMS and leaveTimeMS fields.
  • If a participant leaves and rejoins the call, you can add two entries with the same details but different join/leave times. The participant will display twice in the participant table, but will only count as 1 user.
  • The value for leaveTimeMS is relative to the joinTimeMS in milliseconds, and it can be a negative value.
 "voiceRecords": [
    {
      "startTime": "1737050060753",
      "stopTime": "1737050150341",
      "recordingFile": {
        "filename": "meeting-recording-20250115.opus",
        "fileKey": "/default/meeting-recording-20250115.opus",
        "description": "Recording of conversation"
       },
        "participants": [
          {
            "name": "Ann Nguyen",
            "phone": "555-767-5645",
            "company": "AG Imperial",
            "email": "ann.nguyen@agimperial.com",
            "detail": "Participant",
            "joinTimeMS": 0,
            "leaveTimeMS": 30
          },
          {
            "name": "Sarah Krish",
	    "phone": "555-123-7890",
            "company": "Ag Imperial",
            "email": "sarah.krish@agimperial.com",
            "detail": "Participant",
            "joinTimeMS": 12,
            "leaveTimeMS": 30000
	    "leaveTimeMS": 30000
          },
          {
            "name": "Mary Thorsen",
	    "phone": "555-455-3490",
            "company": "Digiset Capital",
            "email": "mary.thorsen@digisetcapital.com",
            "detail": "Participant",
            "joinTimeMS": 60001
          },
          {
            "name": "Andrea Lacey",
            "phone": "555-321-5467",
            "company": "Lautner Wealth",
	    "email": "alacey@lautnerwealth.com",
            "detail": "Participant",
            "joinTimeMS": 12,
            "leaveTimeMS": 30000
          },
          {
        ]
    }
  ],

Request Info

In the requestInfo object, provide a unique ID (UUID), which you can use for tracking purposes.

{
  "requestInfo": {
    "requestId": "fec433bb-e956-4fb0-b7ed-063ade1945eb"
  },

For more information about the Voice Archiving payload, refer to the API reference.

Time-bounding the calls

You can decide the frequency with which you capture your voice calls for archiving. 

There are a few factors to consider when making this decision in your application:

  • Every request you send will be archived as a separate Archive message.
  • To link separate, related Archive messages to a single voice call, use the callId field in all applicable requests. This groups all applicable Archive messages to the full voice call, saving time for Archive users when searching.
  • Each request you send should contain events which span a timeframe no longer than 24 hours.

Therefore, we suggest adopting one of the following approaches:

ApproachLogicResult
Activity-basedDecide a time value for inactivity, e.g. 30 minutes, 1 hour, which indicates the ‘end’ of a call. After call events have occurred and the inactive period is reached, send an API request with all the preceding call events since the last request was sent.In the Archive, your data accurately represents the start and end of calls based on user activity.
Fixed-time windowCollect all the call events in a fixed period, e.g. 4 hours, but no longer than 24 hours, and send them in a single API request at the end of that period. If there are no events, do not send an API request.The logic for your application is simpler.

Grouping calls across API requests

If needed, you can reuse the same callId in subsequent API requests, so your data displays as a single, sequential call in the Archive.

Ultimately, when a call starts and ends should be based on your compliance and eDiscovery requirements.

For example, this is the first payload you send for a call:

"requestInfo": {
    "requestId": "2c8d4927-433c-4e9a-bf02-ead2f17d1ef2"
 }
"callOverview": {
    //
   "callId": "123456789"
    //
}

If you determine that the call continued after the first API request was sent, you should send another request with a different requestId, but the same callId:

"requestInfo": {
    "requestId": "f8bd53a8-3b72-11ee-be56-0242ac120002"
 }
"callOverview": {
    //
   "callId": "123456789"
    //
}

Tracking your requests

When sending a request to the POST /voice endpoint, you must include a UUID in the requestId field, which identifies this specific API request. The requestId is visible in the Archive when viewing the related voice data, and we log it for data reconciliation purposes, so you should send a unique value in each request.

"requestInfo": {
    "requestId": "2c8d4927-433c-4e9a-bf02-ead2f17d1ef2"
 }

Refer to RFC 4122 for information on the UUID standard.

All your data in the Archive is immutable, so we deliberately don’t support updates. If you send us two different payloads with the same requestId we will still archive them independently.

For all successful API requests, you receive a randomly-generated reconciliationId in the response, which is mapped to the requestId in Global Relay’s system.

Identifying duplicate messages

Improve the transparency of your requests while effectively detecting and managing duplicate submissions without additional calls or logic.

If you post a duplicate message entry to Voice Archiving API, a 202 Accepted HTTP response code is returned. The response code indicates the entry is a duplicate of a previously archived entry, as shown in the following example.

HTTP/1.1 202 ACCEPTED
content-type: application/json
{
"status": "duplicate"
"reconciliationId" : “<reconciliationId>”
}

In the response, the reconciliationId corresponds to the original message entry that was successfully processed, so you can trace the duplicate to its corresponding archived EML entry.

Identifying call visibility to users

To indicate the visibility and scope of a call, you can include the following Boolean-value fields in the callOverview object:

  • isExternal: The call included participants from other companies.
  • isPrivate: Only participants who were invited could join the call; otherwise, the call content is hidden.

Creating custom properties for the call

You can include custom call properties in your archived messages by defining them in the callProperty object. For example, you could create a Call-Quality property field and include values such as High, Medium, and Low.

You then have the option to create a custom x-header for the property, allowing you to search on the x-header in the Archive.

  • To create an x-header for the custom property, set the xheader value to true.
    The name of the x-header will be prefixed with X-GR-OC, e.g. X-GR-OC-Call-Quality, in the archived message.

Creating custom subjects

By using the subjectOverride field in the callOverview object, you can create custom subjects for your archived calls, instead of using the default subject, i.e. Data type:Subtype: CallRecording: number of users, total duration

If the subjectOverride is not set or null, the default subject will display in the Archive, e.g. Zoom: 2 users, 5 minutes 43 seconds

Understanding voice size limits

For the /voice endpoint, the maximum volume of data you can send in a single request is 3.5MB – this does not include file attachments, which are sent to the /files endpoint.

If you exceed 3.5MB, the API returns a 413 error.

When Global Relay receives your data, it is transformed into our Archive message format for optimal indexing. In the rare instance the combined size of the conversation text, metadata, and file attachments exceeds 2GB, the call is split into multiple Archive messages. For more information on attaching voice files, see Archiving voice file attachments.

To locate all the archived messages for a call in the Archive, conduct an Archive header search using the callId you provided in the payload.