

```json
{
  "openapi": "3.0.0",
  "info": {
    "title": "Safe Voice API",
    "version": "v1",
    "description": "## Overview\n\nThe Safe Voice API allows you to create screenings of Vivox voice channels and retrieve the recordings and insights\nof the conversation between the players in that channel.\n\nAdditionally, the results of each screening can be viewed by moderators in our UDash UI tool such that they can\nefficiently take action on problematic behaviour.\n\nFor more information, please refer to our [Documentation](https://docs.unity.com/safe-voice).",
    "contact": {
      "name": "Safe Voice Support",
      "x-slack-channel": "#devs-safevoice",
      "email": "safe-voice-support@unity3d.com"
    }
  },
  "servers": [
    {
      "url": "https://services.api.unity.com"
    }
  ],
  "tags": [
    {
      "name": "Screening"
    },
    {
      "name": "Deletion Request"
    },
    {
      "name": "Data Retrieval Request"
    }
  ],
  "paths": {
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/screenings": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        }
      ],
      "post": {
        "operationId": "create-screening",
        "summary": "Create a Safe Voice Screening",
        "description": "Create a Safe Voice Screening",
        "tags": [
          "Screening"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Processor (safevoice.screening.create)"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Screening"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Screening object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningRetrieve"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponseForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        },
        "callbacks": {
          "onScreeningCompleted": {
            "Callback on screening complete": {
              "post": {
                "requestBody": {
                  "description": "Callback payload sent to the callbackUrl containing the screening.\nThe callbackUrl can either be defined globally in the settings or specified when creating a screening.\nIf specified in a screening request, it will take preference over the global setting.\n",
                  "content": {
                    "application/json": {
                      "schema": {
                        "$ref": "#/components/schemas/ScreeningCallback"
                      }
                    }
                  }
                },
                "responses": {
                  "200": {
                    "description": "Callback acknowledged"
                  }
                }
              }
            }
          },
          "onEvidenceUpload": {
            "Evidence upload on screening complete": {
              "post": {
                "requestBody": {
                  "$ref": "#/components/requestBodies/ScreeningEvidenceUpload"
                },
                "responses": {
                  "200": {
                    "description": "Callback acknowledged"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/screenings/{screeningId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        },
        {
          "$ref": "#/components/parameters/screeningId"
        }
      ],
      "get": {
        "operationId": "get-screening",
        "summary": "Retrieve a Safe Voice Screening",
        "description": "Retrieve a Safe Voice Screening",
        "tags": [
          "Screening"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Processor (safevoice.screening.get)"
            ]
          }
        ],
        "responses": {
          "201": {
            "description": "Screening object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScreeningRetrieve"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/screenings/{screeningId}/player-report-events": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        },
        {
          "$ref": "#/components/parameters/screeningId"
        }
      ],
      "post": {
        "operationId": "add-screening-player-report-events",
        "summary": "Add Player Report Event",
        "description": "Add Player Report Event",
        "tags": [
          "Screening"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Processor (safevoice.screening.create)"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlayerReportEvent"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Event submitted successfully"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponseForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/screenings/{screeningId}/result": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        },
        {
          "$ref": "#/components/parameters/screeningId"
        }
      ],
      "get": {
        "operationId": "get-screening-result",
        "summary": "Retrieve a Safe Voice Screening result",
        "description": "Retrieve a Safe Voice Screening result",
        "tags": [
          "Screening"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Processor (safevoice.screening.get)"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Retrieve AudioSessionResult object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AudioSessionResult"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/data-deletion": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        }
      ],
      "post": {
        "operationId": "create-deletion-request",
        "summary": "Create a Data Deletion Request",
        "description": "Create a Data Deletion Request",
        "tags": [
          "Deletion Request"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Data Deletion (safevoice.deletion.create)"
            ]
          }
        ],
        "requestBody": {
          "description": "Deletion Request object",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeletionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created Deletion Request object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionRequestRetrieve"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponseForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/data-deletion/{deletionId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        },
        {
          "$ref": "#/components/parameters/deletionId"
        }
      ],
      "get": {
        "operationId": "get-deletion-request",
        "summary": "Retrieve a Data Deletion Request",
        "description": "Retrieve a Data Deletion Request",
        "tags": [
          "Deletion Request"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Data Deletion (safevoice.deletion.get)"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Retrieve Deletion Request object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeletionRequestRetrieve"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/players/{playerId}/data-retrieval": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "post": {
        "operationId": "create-retrieval-request",
        "summary": "Create a Data Retrieval Request",
        "description": "Create a Data Retrieval Request",
        "tags": [
          "Data Retrieval Request"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Data Retrieval (safevoice.retrieval.create)"
            ]
          }
        ],
        "requestBody": {
          "description": "Data Retrieval Request object",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DataRetrievalRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successfully created Data Retrieval Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataRetrievalObject"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ErrorResponseBadRequest"
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponseForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    },
    "/safevoice/v1/organizations/{organizationId}/projects/{projectId}/environments/{environmentId}/players/{playerId}/data-retrieval/{dataRetrievalId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/organizationId"
        },
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/environmentId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        },
        {
          "$ref": "#/components/parameters/dataRetrievalId"
        }
      ],
      "get": {
        "operationId": "get-retrieval-request",
        "summary": "Get a Data Retrieval Request",
        "description": "Get a Data Retrieval Request",
        "tags": [
          "Data Retrieval Request"
        ],
        "security": [
          {
            "ServiceAccount": [
              "Safe Voice Data Retrieval (safevoice.retrieval.get)"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "Get Data Retrieval Request object",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataRetrievalObject"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/ErrorResponseUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ErrorResponseForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ErrorResponseNotFound"
          },
          "500": {
            "$ref": "#/components/responses/ErrorResponseInternalServerError"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "organizationId": {
        "name": "organizationId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "ID of the organization"
      },
      "projectId": {
        "name": "projectId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "ID of the project"
      },
      "environmentId": {
        "name": "environmentId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "ID of the environment"
      },
      "screeningId": {
        "name": "screeningId",
        "in": "path",
        "description": "The unique id of the screening",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "playerId": {
        "name": "playerId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "ID of the player"
      },
      "deletionId": {
        "name": "deletionId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        },
        "description": "ID of the deletion request"
      },
      "dataRetrievalId": {
        "name": "dataRetrievalId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "ID of the data retrieval request"
      }
    },
    "schemas": {
      "EventType": {
        "type": "string",
        "title": "Event triggering the audio session processing",
        "description": "The event type responsible for the audio session processing.\nFor instance:\n  * report: screening created from user report.\n  * unreported: screening created by random match sample.\n  * sample: Deprecated, use `unreported` instead.\n  * mute: screening created based on mute events.\n  * unspecified: screening created by an unspecified event.\n  * unknown: Deprecated, use `unspecified` instead.\n"
      },
      "ScreeningRetrieve": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique screening ID",
            "readOnly": true
          },
          "createdAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "processingStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProcessingStatusEnum"
              }
            ],
            "readOnly": true
          },
          "errorDescription": {
            "type": "string",
            "description": "Human readable description of what happened.",
            "readOnly": true
          },
          "errorCode": {
            "type": "string",
            "description": "Service specific error code. Check out the specific error codes in our [Documentation](https://docs.unity.com/ugs/en-us/manual/safe-voice/manual/troubleshooting)",
            "readOnly": true
          },
          "organization": {
            "type": "string",
            "format": "uuid",
            "description": "Organization ID",
            "readOnly": true
          },
          "project": {
            "type": "string",
            "format": "uuid",
            "description": "Project ID",
            "readOnly": true
          },
          "environment": {
            "type": "string",
            "format": "uuid",
            "description": "Environment ID",
            "readOnly": true
          },
          "targetUri": {
            "type": "string",
            "description": "The URI of the channel that you want to screen. \nTo learn more about the Vivox channel URI structure, refer to the [Channel URI structure](https://docs.vivox.com/v5/general/core/5_13_0/en-us/Default.htm#server-to-server-api-reference/uri/channel-uri.htm) section in the Vivox documentation.\n",
            "example": "sip:confctl-g-issuer.lobby@vdx5.vivox.com."
          },
          "receiveResults": {
            "type": "boolean",
            "description": "Enables uploading listenable audio to your bucket together with analysis results.\nDefaults to false.\nIf you wish to store data on your own storage bucket, you can set `receiveResults` to `true` and provide `destinationCredentials` for you storage bucket.\n"
          },
          "callbackUrl": {
            "type": "string",
            "format": "uri",
            "description": "Enter the full url of where your server is listening to receive error and status callbacks.\nSafe Voice will invoke this endpoint once the screening is complete, or if there was an error.\n"
          },
          "eventType": {
            "$ref": "#/components/schemas/EventType"
          },
          "playerReportEvents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlayerReportEvent"
            },
            "maxItems": 100
          },
          "customMetadata": {
            "$ref": "#/components/schemas/CustomMetadata"
          },
          "players": {
            "$ref": "#/components/schemas/PlayersField"
          },
          "perspectiveTarget": {
            "type": "string",
            "description": "Player ID that will be the focal point of the recording. If perspectiveTarget is defined, Safe Voice will record all interactions involving this player from their perspective.\nIf consent enforcement is enabled, all present players must have given consent before submitting the request.\n"
          }
        }
      },
      "Screening": {
        "type": "object",
        "properties": {
          "targetUri": {
            "type": "string",
            "description": "The URI of the channel that you want to screen. \nTo learn more about the Vivox channel URI structure, refer to the [Channel URI structure](https://docs.vivox.com/v5/general/core/5_13_0/en-us/Default.htm#server-to-server-api-reference/uri/channel-uri.htm) section in the Vivox documentation.\n",
            "example": "sip:confctl-g-issuer.lobby@vdx5.vivox.com."
          },
          "history": {
            "type": "integer",
            "description": "How far back you wish to record. Max is 45 minutes\n"
          },
          "receiveResults": {
            "type": "boolean",
            "description": "Enables uploading listenable audio to your bucket together with analysis results.\nDefaults to false.\nIf you wish to store data on your own storage bucket, you can set `receiveResults` to `true` and provide `destinationCredentials` for you storage bucket.\n",
            "default": false
          },
          "destinationCredentials": {
            "description": "Credentials for one of the supported destination storage solutions:\n  * AWS S3\n",
            "oneOf": [
              {
                "$ref": "#/components/schemas/S3AccessCredentials"
              }
            ]
          },
          "callbackUrl": {
            "type": "string",
            "format": "uri",
            "description": "Enter the full url of where your server is listening to receive error and status callbacks.\nSafe Voice will invoke this endpoint once the screening is complete, or if there was an error.\nSafe Voice will send a POST request with the same body as a GET screening would return.\nSpecifying a callbackKey together with the callbackUrl is required.\n"
          },
          "callbackKey": {
            "type": "string",
            "description": "If you would like to validate that the callbacks sent to your callback endpoint are from Safe Voice,\nyou can specify this parameter.\nWe will sent the content of this field in the 'Authorization' header in the callback request as a basic auth header.\nThis means the header will look like this: \"Authorization\": \"callbackKey\"\n"
          },
          "eventType": {
            "$ref": "#/components/schemas/EventType"
          },
          "playerReportEvents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlayerReportEvent"
            },
            "maxItems": 100
          },
          "customMetadata": {
            "$ref": "#/components/schemas/CustomMetadata"
          },
          "players": {
            "$ref": "#/components/schemas/PlayersField"
          },
          "perspectiveTarget": {
            "type": "string",
            "description": "Player ID that will be the focal point of the recording. If perspectiveTarget is defined, Safe Voice will record all interactions involving this player from their perspective.\nIf consent enforcement is enabled, all present players must have given consent before submitting the request.\n"
          }
        },
        "required": [
          "targetUri",
          "history",
          "eventType"
        ]
      },
      "ScreeningCallback": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique screening ID",
            "readOnly": true
          },
          "organization": {
            "type": "string",
            "format": "uuid",
            "description": "Organization ID",
            "readOnly": true
          },
          "project": {
            "type": "string",
            "format": "uuid",
            "description": "Project ID",
            "readOnly": true
          },
          "environment": {
            "type": "string",
            "format": "uuid",
            "description": "Environment ID",
            "readOnly": true
          },
          "createdAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "processingStatus": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProcessingStatusEnum"
              }
            ],
            "readOnly": true
          },
          "errorDescription": {
            "type": "string",
            "description": "Human readable description of what happened.",
            "readOnly": true
          },
          "errorCode": {
            "type": "string",
            "description": "Service specific error code. Check out the specific error codes in our [Documentation](https://docs.unity.com/ugs/en-us/manual/safe-voice/manual/troubleshooting)",
            "readOnly": true
          },
          "targetUri": {
            "type": "string",
            "description": "The URI of the channel that you want to screen. \nTo learn more about the Vivox channel URI structure, refer to the [Channel URI structure](https://docs.vivox.com/v5/general/core/5_13_0/en-us/Default.htm#server-to-server-api-reference/uri/channel-uri.htm) section in the Vivox documentation.\n",
            "example": "sip:confctl-g-issuer.lobby@vdx5.vivox.com."
          },
          "eventType": {
            "$ref": "#/components/schemas/EventType"
          },
          "customMetadata": {
            "$ref": "#/components/schemas/CustomMetadata"
          }
        }
      },
      "AudioSessionResultStatusEnum": {
        "enum": [
          "LIVE",
          "ARCHIVED",
          "EXPIRED",
          "DISCARDED",
          "RESOLVED"
        ],
        "type": "string"
      },
      "PlayerReportEvent": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "reportType": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Label defining the report type"
          },
          "reportReason": {
            "type": "string",
            "description": "Description of the reported incident"
          },
          "reportedPlayerId": {
            "$ref": "#/components/schemas/PlayerId"
          },
          "reporterPlayerId": {
            "$ref": "#/components/schemas/PlayerId"
          }
        },
        "required": [
          "reportType",
          "reporterPlayerId"
        ]
      },
      "AudioSessionMetadata": {
        "type": "object",
        "title": "Audio Session Metadata Schema",
        "maxProperties": 50,
        "additionalProperties": {
          "type": "string",
          "maxLength": 500
        },
        "properties": {
          "eventType": {
            "$ref": "#/components/schemas/EventType"
          },
          "playerReportEvents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlayerReportEvent"
            }
          }
        }
      },
      "AudioSessionResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique result id",
            "readOnly": true
          },
          "metadata": {
            "$ref": "#/components/schemas/AudioSessionMetadata"
          },
          "result": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/AudioSessionResultResultField"
              },
              {
                "$ref": "#/components/schemas/AudioSessionResultEmptyResultField"
              }
            ]
          },
          "createdAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "resolvedAt": {
            "$ref": "#/components/schemas/NullableTimestamp"
          },
          "samplingInterval": {
            "type": "string",
            "readOnly": true
          },
          "duration": {
            "type": "number",
            "readOnly": true
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AudioSessionResultStatusEnum"
              }
            ],
            "readOnly": true
          }
        },
        "required": [
          "createdAt",
          "duration",
          "id",
          "resolvedAt",
          "result",
          "samplingInterval",
          "status"
        ]
      },
      "AudioSessionResultResultField": {
        "type": "object",
        "properties": {
          "players": {
            "type": "array",
            "description": "list of players in this session",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "$ref": "#/components/schemas/PlayerId"
                },
                "displayName": {
                  "type": "string",
                  "description": "The player display name"
                },
                "events": {
                  "description": "List of events that happened during this session related to this player.\n",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "sourcePlayerId": {
                        "$ref": "#/components/schemas/PlayerId"
                      },
                      "action": {
                        "type": "string",
                        "enum": [
                          "join",
                          "leave",
                          "mute",
                          "unmute"
                        ]
                      },
                      "targetPlayerId": {
                        "$ref": "#/components/schemas/PlayerId"
                      },
                      "timestamp": {
                        "$ref": "#/components/schemas/SessionTimestamp"
                      }
                    }
                  }
                },
                "characteristics": {
                  "type": "array",
                  "description": "List of characteristics identified for this player.\n",
                  "items": {
                    "type": "object",
                    "properties": {
                      "category": {
                        "type": "string"
                      },
                      "value": {
                        "type": "string",
                        "enum": [
                          "feminine",
                          "masculine",
                          "unknown",
                          "child"
                        ]
                      },
                      "confidence": {
                        "$ref": "#/components/schemas/SafeVoiceScore"
                      }
                    }
                  }
                },
                "languages": {
                  "type": "array",
                  "description": "List of languages found in this player's track and the ratio for each language.\nThe languageRatio is the percentage of the total speech content that is a certain language.\n",
                  "items": {
                    "type": "object",
                    "properties": {
                      "language": {
                        "$ref": "#/components/schemas/SafeVoiceLanguageCodes"
                      },
                      "languageRatio": {
                        "$ref": "#/components/schemas/SafeVoiceScore"
                      }
                    }
                  }
                },
                "scores": {
                  "type": "array",
                  "description": "Contains a list of session level scores.\nThere are the default scores: \"toxicity\", \"disruption\", \"positive_play\"\nAnd there can also be \"custom scores\" that are defined in the Safe Voice settings, custom to your community.\n",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string",
                        "description": "The ID of the score. It can either be a default score from Safe Voice or a custom score created by the user.\n"
                      },
                      "class": {
                        "$ref": "#/components/schemas/SafeVoiceOrdinalScore"
                      },
                      "value": {
                        "$ref": "#/components/schemas/SafeVoiceScore"
                      }
                    }
                  }
                },
                "segments": {
                  "type": "array",
                  "description": "The segment IDs this player is associated with.\n",
                  "items": {
                    "type": "string"
                  }
                },
                "trackId": {
                  "type": "string",
                  "description": "The ID of the player's track."
                },
                "url": {
                  "type": "string",
                  "description": "The URL of the player's track."
                },
                "waveform": {
                  "type": "array",
                  "description": "Array representing the waveform data",
                  "items": {
                    "type": "array",
                    "description": "A pair of integers representing a data point",
                    "items": {
                      "type": "integer",
                      "description": "A single value in the waveform",
                      "example": 0
                    }
                  }
                },
                "isAudioDeleted": {
                  "type": "string",
                  "description": "Indicates whether the player's audio track has been deleted."
                }
              },
              "required": [
                "id",
                "displayName",
                "events",
                "characteristics",
                "languages",
                "scores",
                "segments",
                "trackId",
                "url",
                "waveform",
                "isAudioDeleted"
              ]
            }
          },
          "overallRiskScore": {
            "type": "object",
            "description": "Presents a generic risk score for the session based on the maximum weighted scores from the different categories.\nIt produces higher values if there is toxicity exposure to a certain type of player (e.g. children, women).\n",
            "properties": {
              "value": {
                "$ref": "#/components/schemas/SafeVoiceScore"
              },
              "class": {
                "$ref": "#/components/schemas/SafeVoiceOrdinalScore"
              }
            }
          },
          "scores": {
            "type": "array",
            "description": "Contains a list of session level scores.\nThere are the default scores: \"toxicity\", \"disruption\", \"positive_play\"\nAnd there can also be \"custom scores\" that are defined in the Safe Voice settings, custom to your community.\n",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "The ID of the score. It can either be a default score from Safe Voice or a custom score created by the user.\n"
                },
                "value": {
                  "$ref": "#/components/schemas/SafeVoiceScore"
                },
                "class": {
                  "$ref": "#/components/schemas/SafeVoiceOrdinalScore"
                }
              }
            }
          },
          "moments": {
            "type": "array",
            "description": "The moments key holds a list of notable moments in the audio session.",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "playerId": {
                  "type": "string"
                },
                "timestampStart": {
                  "$ref": "#/components/schemas/SessionTimestamp"
                },
                "timestampEnd": {
                  "$ref": "#/components/schemas/SessionTimestamp"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "toxicity_detection",
                    "disruption",
                    "unsupported_language",
                    "positive_play"
                  ]
                },
                "score": {
                  "$ref": "#/components/schemas/SafeVoiceScore"
                },
                "tags": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "enum": [
                          "verbal_abuse",
                          "obscene",
                          "threat",
                          "insult",
                          "identity_attack",
                          "problematic_speech",
                          "loud_speech",
                          "very_loud_speech",
                          "speech",
                          "loud_music",
                          "very_loud_music",
                          "music",
                          "loud_noise",
                          "very_loud_noise",
                          "noise",
                          "energetic",
                          "low_energy",
                          "positive_human_sounds",
                          "negative_human_sounds",
                          "collaborative",
                          "encouragement",
                          "gratitude",
                          "praise"
                        ]
                      },
                      "category": {
                        "type": "string",
                        "enum": [
                          "arousal",
                          "acoustic_content",
                          "toxicity",
                          "speech_toxicity",
                          "expression",
                          "language",
                          "human_sounds",
                          "positive_play"
                        ]
                      },
                      "attributes": {
                        "type": "object",
                        "additionalProperties": true
                      }
                    }
                  }
                },
                "transcription": {
                  "type": "string"
                }
              }
            }
          }
        },
        "required": [
          "players",
          "scores",
          "moments",
          "overallRiskScore"
        ]
      },
      "AudioSessionResultEmptyResultField": {
        "type": "object",
        "additionalProperties": false
      },
      "ProcessingStatusEnum": {
        "enum": [
          "NEW",
          "PRELOADING_TRACKS",
          "READY_FOR_PROCESSING",
          "PROCESSING",
          "ERROR",
          "DONE",
          "RECORDING",
          "PARTIAL",
          "IGNORED"
        ],
        "type": "string"
      },
      "CustomMetadata": {
        "type": "object",
        "title": "Custom Metadata Schema",
        "description": "The customMetadata object can be used to provide additional data to SafeVoice.\nThis data will be available in the result object of the processing results\n",
        "maxProperties": 50,
        "additionalProperties": {
          "type": "string",
          "maxLength": 500
        }
      },
      "PlayersField": {
        "type": "array",
        "description": "A list of player data.\nIf player data is provided, Safe Voice will only record and process\nthe audio of the players in this list.\nIt's important that the playerId field provided matches the player id that was used to login to vivox.\nIf the players list is not provided, all players will be recorded and processed.\n",
        "items": {
          "type": "object",
          "title": "Player information",
          "properties": {
            "playerId": {
              "$ref": "#/components/schemas/PlayerId"
            },
            "displayName": {
              "type": "string",
              "description": "If a displayName is provided for a player, it will be displayed in the Safe Voice UI.\nThis field can be used to provide a custom player ID to enable moderators to action on findings more directly without having to translate player IDs.\n"
            }
          },
          "required": [
            "playerId"
          ]
        }
      },
      "PlayerId": {
        "type": "string",
        "description": "The player ID used to login to Vivox. Learn more about player IDs in our [Developer Documentation](https://docs.unity.com/ugs/en-us/manual/sv/manual/integration-guide/make-a-request#Player_IDs).\n"
      },
      "S3AccessCredentials": {
        "type": "object",
        "required": [
          "bucket",
          "accessKeyId",
          "secretAccessKey"
        ],
        "properties": {
          "bucket": {
            "type": "string",
            "description": "Bucket URI"
          },
          "accessKeyId": {
            "type": "string",
            "format": "password"
          },
          "secretAccessKey": {
            "type": "string",
            "format": "password"
          }
        },
        "description": "Internal Server Error"
      },
      "Timestamp": {
        "type": "string",
        "format": "ISO8601Micros",
        "readOnly": true,
        "description": "Timestamp with the format: YYYY-MM-DDTHH:mm:ss.ssssssZ"
      },
      "NullableTimestamp": {
        "type": "string",
        "format": "ISO8601Micros",
        "readOnly": true,
        "nullable": true,
        "description": "Timestamp with the format: YYYY-MM-DDTHH:mm:ss.ssssssZ"
      },
      "SessionTimestamp": {
        "type": "number",
        "readOnly": true,
        "description": "Timestamp within a session. Specifying the number of milliseconds from the beginning of the session."
      },
      "SafeVoiceScore": {
        "description": "Score value between 0 and 1.",
        "example": 0.45,
        "type": "number",
        "minimum": 0,
        "maximum": 1
      },
      "SafeVoiceOrdinalScore": {
        "type": "string",
        "description": "Ordinal score class.",
        "example": "high",
        "enum": [
          "none",
          "low",
          "medium",
          "high"
        ]
      },
      "SafeVoiceLanguageCodes": {
        "type": "string",
        "description": "Language code, e.g. `en`",
        "example": "en",
        "enum": [
          "en",
          "zh",
          "de",
          "es",
          "ru",
          "ko",
          "fr",
          "ja",
          "pt",
          "tr",
          "pl",
          "ca",
          "nl",
          "ar",
          "sv",
          "it",
          "id",
          "hi",
          "fi",
          "vi",
          "he",
          "uk",
          "el",
          "ms",
          "cs",
          "ro",
          "da",
          "hu",
          "ta",
          "no",
          "th",
          "ur",
          "hr",
          "bg",
          "lt",
          "la",
          "mi",
          "ml",
          "cy",
          "sk",
          "te",
          "fa",
          "lv",
          "bn",
          "sr",
          "az",
          "sl",
          "kn",
          "et",
          "mk",
          "br",
          "eu",
          "is",
          "hy",
          "ne",
          "mn",
          "bs",
          "kk",
          "sq",
          "sw",
          "gl",
          "mr",
          "pa",
          "si",
          "km",
          "sn",
          "yo",
          "so",
          "af",
          "oc",
          "ka",
          "be",
          "tg",
          "sd",
          "gu",
          "am",
          "yi",
          "lo",
          "uz",
          "fo",
          "ht",
          "ps",
          "tk",
          "nn",
          "mt",
          "sa",
          "lb",
          "my",
          "bo",
          "tl",
          "mg",
          "as",
          "tt",
          "haw",
          "ln",
          "ha",
          "ba",
          "jw",
          "su"
        ]
      },
      "BasicErrorResponse": {
        "description": "Referenced from - https://tools.ietf.org/html/rfc7807#page-3 Consumers MUST use the 'type' string as the primary identifier for the problem type; the 'title' string is advisory and included only for users who are not aware of the semantics of the URI and do not have the ability to discover them (for example, offline log analysis). Consumers SHOULD NOT automatically dereference the type URI. The \"status\" member, if present, is only advisory; it conveys the HTTP status code used for the convenience of the consumer. Generators MUST use the same status code in the actual HTTP response, to assure that generic HTTP software that does not understand this format still behaves correctly.  See Section 5 for further caveats regarding its use. Consumers can use the status member to determine what the original status code used by the generator was, in cases where it has been changed (for example, by an intermediary or cache), and when message bodies persist without HTTP information.  Generic HTTP software still uses the HTTP status code. The \"detail\" member, if present, should focus on helping the client correct the problem, rather than giving debugging information.\n",
        "type": "object",
        "x-examples": {
          "example-1": {
            "type": "problems/basic",
            "title": "Internal Server Error",
            "status": 500,
            "code": 43000,
            "detail": "unexpected error",
            "requestId": "aad109f8-033f-4a24-8b77-5032eb3a6158"
          }
        },
        "properties": {
          "type": {
            "type": "string",
            "description": "A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (e.g., using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\"."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (e.g., using proactive content negotiation; see [RFC7231], Section 3.4).",
            "example": "Bad Request"
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem.",
            "example": 400
          },
          "code": {
            "type": "integer",
            "description": "Service specific error code. Check out the specific error codes in our [Documentation](https://docs.unity.com/ugs/en-us/manual/safe-voice/manual/troubleshooting)\n"
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem.",
            "example": "Failed to parse request body. Error: Unexpected end of JSON input"
          },
          "instance": {
            "type": "string",
            "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced."
          },
          "details": {
            "type": "array",
            "description": "Machine readable service specific errors.",
            "items": {
              "type": "object"
            },
            "maxItems": 100
          },
          "requestId": {
            "type": "string",
            "format": "uuid",
            "description": "Request correlation ID",
            "example": "aad109f8-033f-4a24-8b77-5032eb3a6158"
          }
        },
        "required": [
          "type"
        ]
      },
      "ConflictErrorResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/BasicErrorResponse"
          },
          {
            "type": "object",
            "title": "ConflictErrorResponse",
            "example": {
              "type": "problems/basic",
              "title": "Conflict",
              "status": 409,
              "code": 58,
              "detail": "Deletion request already exists with the same player ID"
            }
          }
        ]
      },
      "DeletionRequest": {
        "type": "object",
        "properties": {
          "playerId": {
            "$ref": "#/components/schemas/PlayerId"
          },
          "callbackUrl": {
            "type": "string",
            "description": "Enter the full url of where your server is listening to receive error and status callbacks.\nSafe Voice will invoke this endpoint once the deletion request is complete, or if there was an error.\nSafe Voice will send a POST request with the same body as a GET /data-deletion/{deletionId} would return.\nSpecifying a callbackKey together with the callbackUrl is required.\n",
            "format": "url"
          },
          "callbackKey": {
            "type": "string",
            "description": "If you would like to validate that the callbacks sent to your callback endpoint are from Safe Voice,\nyou can specify this parameter.\nWe will sent the content of this field in the 'Authorization' header in the callback request as a basic auth header.\nThis means the header will look like this: \"Authorization\": \"callbackKey\"\n"
          }
        }
      },
      "DeletionRequestRetrieve": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique deletion request id",
            "readOnly": true
          },
          "createdAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeletionRequestStatusEnum"
              }
            ],
            "readOnly": true
          },
          "reason": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DeletionRequestReasonEnum"
              }
            ],
            "readOnly": true
          },
          "organization": {
            "type": "string",
            "format": "uuid",
            "description": "Organization ID",
            "readOnly": true
          },
          "project": {
            "type": "string",
            "format": "uuid",
            "description": "Project ID",
            "readOnly": true
          },
          "environment": {
            "type": "string",
            "format": "uuid",
            "description": "Environment ID",
            "readOnly": true
          },
          "audioSessionResults": {
            "type": "array",
            "description": "List of session IDs that were deleted.\n",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "tracks": {
            "type": "array",
            "description": "List of track IDs that were deleted.\n",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "moments": {
            "type": "array",
            "description": "List of moment IDs that were deleted.\n",
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "playerId": {
            "$ref": "#/components/schemas/PlayerId"
          },
          "callbackUrl": {
            "type": "string",
            "description": "Enter the full url of where your server is listening to receive error and status callbacks.\nSafe Voice will invoke this endpoint once the deletion request is complete, or if there was an error.\nSafe Voice will send a POST request with the same body as a GET /data-deletion/{deletionId} would return.\n",
            "format": "url"
          }
        },
        "required": [
          "audioSession",
          "createdAt",
          "updatedAt",
          "id",
          "status",
          "project",
          "reason",
          "organization",
          "environment"
        ]
      },
      "DeletionRequestReasonEnum": {
        "enum": [
          "USER",
          "EXPIRED"
        ],
        "type": "string"
      },
      "DeletionRequestStatusEnum": {
        "enum": [
          "NEW",
          "DELETING",
          "DONE",
          "ERROR"
        ],
        "type": "string"
      },
      "DataRetrievalObject": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "Unique data retrieval request id"
          },
          "organization": {
            "type": "string",
            "format": "uuid",
            "description": "Organization ID"
          },
          "project": {
            "type": "string",
            "format": "uuid",
            "description": "Project ID"
          },
          "environment": {
            "type": "string",
            "format": "uuid",
            "description": "Environment ID"
          },
          "playerId": {
            "$ref": "#/components/schemas/PlayerId"
          },
          "createdAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/Timestamp"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DataRetrievalRequestStatusEnum"
              }
            ]
          },
          "errorCode": {
            "type": "string",
            "description": "Service specific error code. Check out the specific error codes in our [Documentation](https://docs.unity.com/ugs/en-us/manual/safe-voice/manual/troubleshooting)."
          },
          "errorDescription": {
            "type": "string",
            "description": "Human readable description of what happened."
          },
          "callbackUrl": {
            "type": "string",
            "description": "Enter the full url of where your server is listening to receive error and status callbacks.\nSafe Voice will invoke this endpoint once the data retrieval request is complete, or if there was an error.\nSafe Voice will send a POST request with the same body as a GET /data-retrieval/{dataRetrievalId} would return.\n",
            "format": "url"
          },
          "transcriptionsUrl": {
            "type": "string",
            "description": "Location to download the transcriptions for a player. The URL will expire after 7 days.",
            "format": "uri"
          }
        },
        "required": [
          "id",
          "organization",
          "project",
          "environment",
          "playerId",
          "createdAt",
          "updatedAt",
          "status"
        ]
      },
      "DataRetrievalRequest": {
        "type": "object",
        "properties": {
          "callbackKey": {
            "type": "string",
            "description": "If you would like to validate that the callbacks sent to your callback endpoint are from Safe Voice,\nyou can specify this parameter.\nWe will sent the content of this field in the 'Authorization' header in the callback request as a basic auth header.\nThis means the header will look like this: \"Authorization\": \"callbackKey\"\n"
          },
          "callbackUrl": {
            "type": "string",
            "description": "Enter the full url of where your server is listening to receive error and status callbacks.\nSafe Voice will invoke this endpoint once the data retrieval request is complete, or if there was an error.\nSafe Voice will send a POST request with the same body as a GET /data-retrieval/{dataRetrievalId} would return.\nSpecifying a callbackKey together with the callbackUrl is required.\n",
            "format": "uri"
          }
        }
      },
      "DataRetrievalRequestStatusEnum": {
        "enum": [
          "NEW",
          "COLLECTING",
          "DONE",
          "ERROR"
        ],
        "type": "string"
      }
    },
    "requestBodies": {
      "ScreeningEvidenceUpload": {
        "description": "Evidence upload payload sent to the results endpoint specified in the settings.",
        "content": {
          "multipart/form-data": {
            "schema": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Unique screening ID"
                },
                "organization": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Organization ID"
                },
                "project": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Project ID"
                },
                "environment": {
                  "type": "string",
                  "format": "uuid",
                  "description": "Environment ID"
                },
                "createdAt": {
                  "$ref": "#/components/schemas/Timestamp"
                },
                "processingStatus": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ProcessingStatusEnum"
                    }
                  ],
                  "readOnly": true
                },
                "errorDescription": {
                  "type": "string",
                  "description": "Human readable description of what happened.",
                  "readOnly": true
                },
                "errorCode": {
                  "type": "string",
                  "description": "Service specific error code. Check out the specific error codes in our [Documentation](https://docs.unity.com/ugs/en-us/manual/safe-voice/manual/troubleshooting)",
                  "readOnly": true
                },
                "targetUri": {
                  "type": "string",
                  "description": "The URI of the channel that you want to screen. \nTo learn more about the Vivox channel URI structure, refer to the [Channel URI structure](https://docs.vivox.com/v5/general/core/5_13_0/en-us/Default.htm#server-to-server-api-reference/uri/channel-uri.htm) section in the Vivox documentation.\n",
                  "example": "sip:confctl-g-issuer.lobby@vdx5.vivox.com."
                },
                "eventType": {
                  "$ref": "#/components/schemas/EventType"
                },
                "customMetadata": {
                  "$ref": "#/components/schemas/CustomMetadata"
                },
                "resultData": {
                  "type": "string",
                  "format": "binary",
                  "description": "ZIP file containing\n  * Structured analysis JSON (result.json)\n  * Audio files (audio/<trackId>.aac)\nThe trackId for each player can be found in the result.json payload's players list.\n"
                }
              }
            },
            "encoding": {
              "resultData": {
                "contentType": "application/zip"
              }
            }
          }
        }
      }
    },
    "responses": {
      "Conflict": {
        "description": "Conflict",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ConflictErrorResponse"
            }
          }
        }
      },
      "ErrorResponseBadRequest": {
        "description": "Bad Request. Returned code indicates one of:\n   - Request parameter validation failure\n   - Other\n See the response schema for more details",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "ErrorResponseForbidden": {
        "description": "Forbidden",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "ErrorResponseNotFound": {
        "description": "Not Found",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "ErrorResponseUnauthorized": {
        "description": "Unauthorized",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "ErrorResponseInternalServerError": {
        "description": "Unauthorized",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "ServiceAccount": {
        "type": "http",
        "scheme": "basic",
        "description": "To get started with Authentication, please visit the [Service Account Authentication section](https://services.docs.unity.com/docs/service-account-auth)."
      }
    }
  }
}
```