# Authentication Source: https://docs.vatis.tech/api-reference/authentication Authenticate to Vatis Streams API The Vatis Streams API offers the following authentication schemas: * **Client credentials**: Authenticate using the `Client Id` and `Client Secret` provided by Vatis Tech Platform * **Authorization token**: Authenticate using an `access_token` obtained by exchanging the client credentials * **API Key**: Authenticate using an `api key` provided by Vatis Tech Platform Get the `Client Id` and `Client Secret` from your [API Dashboard](https://vatis.tech/app/playground/transcribe) There are two ways to set the client credentials on each request: 1. Set the `X-Client-Id` and `X-Client-Secret` headers 2. Set the `client_id` and `client_secret` query parameters Send the credentials as query parameters with extra caution as they may get logged Get the `Client Id` and `Client Secret` from your Vatis Tech Platform account Request the access token as illustrated below: ```bash curl --request POST \ --url https://auth.vatis.tech/realms/vatistech/protocol/openid-connect/token \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data 'client_id=string' \ --data 'client_secret=string' \ --data grant_type=client_credentials ``` [Try it out](https://docs.vatis.tech/api-reference/commons/authenticate) In the response, you will get an `access_token` which you can use to authenticate your requests. ```json { "access_token": "eyJhb...", "expires_in": 600, "token_type": "Bearer", ... } ``` It's recommended to obtain a new access token before each workflow execution There are two ways to set the authorization token on each subsequent request: 1. Set the `Authorization` header with the `Bearer [token]` value 2. Set the `access_token` as a query parameter having the token as the value It's recommended to set the token as a header Get the `API key` from your [API Dashboard](https://vatis.tech/app/playground/transcribe) There are two ways to set the API key on each subsequent request: 1. Set the `Authorization` header with the `Basic [api_key]` value 2. Set the `access_token` as a query parameter having the API key as the value Send the API key as query parameter with extra caution as it may get logged # Authenticate Source: https://docs.vatis.tech/api-reference/commons/authenticate POST /realms/vatistech/protocol/openid-connect/token # Export Source: https://docs.vatis.tech/api-reference/export/exports-a-stream-of-data-in-various-formats get /export-service/api/v1/export/{exportFormat} Exports results of one or more streams in various formats # Upload Source: https://docs.vatis.tech/api-reference/gateway/upload post /http-gateway/api/v1/upload Upload a stream of bytes to a new stream Please note the body can be any binary data. Use the [Swagger UI](https://http-gateway.vatis.tech/swagger-ui/index.html) to test this endpoint. # Introduction Source: https://docs.vatis.tech/api-reference/introduction Vatis Streams API reference Vatis Streams API is a RESTful API that aims to provide a simple and easy way to interact with the Vatis Streams platform. The API is built using the OpenAPI specification and is available for public use. ## Examples Explore our [GitHub samples repository](https://github.com/Vatis-Tech/vatis-streams-samples) to find examples for the programming languages and the use-case that fits you best. ## Swagger docs Feel free to check out the Swagger documentation for each individual service in out infrastructure # null Source: https://docs.vatis.tech/api-reference/schemas/egress/diarization-response # null Source: https://docs.vatis.tech/api-reference/schemas/egress/llm-response # null Source: https://docs.vatis.tech/api-reference/schemas/egress/stream-sink-message # null Source: https://docs.vatis.tech/api-reference/schemas/egress/transcription-response # null Source: https://docs.vatis.tech/api-reference/schemas/error/error-response # Internal error names Source: https://docs.vatis.tech/api-reference/schemas/error/internal-error-name # null Source: https://docs.vatis.tech/api-reference/schemas/export/audio-intelligence-response # null Source: https://docs.vatis.tech/api-reference/schemas/http-gateway/stream-configuration # null Source: https://docs.vatis.tech/api-reference/schemas/webhook/event-payload/group-state-changed-event # null Source: https://docs.vatis.tech/api-reference/schemas/webhook/event-payload/group-stream-joined-event # null Source: https://docs.vatis.tech/api-reference/schemas/webhook/event-payload/stream-gateway-state-event # null Source: https://docs.vatis.tech/api-reference/schemas/webhook/event-payload/stream-processor-state-event # null Source: https://docs.vatis.tech/api-reference/schemas/webhook/event-payload/stream-state-event # null Source: https://docs.vatis.tech/api-reference/schemas/webhook/webhook-event # null Source: https://docs.vatis.tech/api-reference/schemas/websocket/configuration # End of Stream Source: https://docs.vatis.tech/api-reference/schemas/websocket/end-of-stream Message type. ```json { "type": "END_OF_STREAM" } ``` # null Source: https://docs.vatis.tech/api-reference/schemas/websocket/error # null Source: https://docs.vatis.tech/api-reference/schemas/websocket/keep-alive # null Source: https://docs.vatis.tech/api-reference/schemas/websocket/response # null Source: https://docs.vatis.tech/api-reference/schemas/websocket/stream-metadata # Find all Source: https://docs.vatis.tech/api-reference/stream-configuration/processor-declaration-resource-impl/find-all get /stream-configuration-service/api/v1/processor-declarations Retrieves all the processor declarations the user can access in a paginated manner # Find all Source: https://docs.vatis.tech/api-reference/stream-configuration/stream-configuration-template-resource-impl/find-all get /stream-configuration-service/api/v1/stream-configuration-templates Retrieves all the stream configuration templates the user can access in a paginated manner # Patch by id Source: https://docs.vatis.tech/api-reference/stream-configuration/stream-configuration-template-resource-impl/patch-by-id patch /stream-configuration-service/api/v1/stream-configuration-templates/{streamConfigurationTemplateId} Retrieves the stream configuration template with patches applied. # Cancel Source: https://docs.vatis.tech/api-reference/streams/stream-resource-impl/cancel put /stream-service/api/v1/streams/{streamId}/cancel Cancels a stream. This operation can be performed by a gateway, on behalf of the user # Find all Source: https://docs.vatis.tech/api-reference/streams/stream-resource-impl/find-all get /stream-service/api/v1/streams Find all streams the current user has access to in a paginated manner # Find by id Source: https://docs.vatis.tech/api-reference/streams/stream-resource-impl/find-by-id get /stream-service/api/v1/streams/{streamId} Retrieves a stream by id # Get components Source: https://docs.vatis.tech/api-reference/streams/stream-resource-impl/get-components get /stream-service/api/v1/streams/{streamId}/components Get the components of a stream # Stream usage Source: https://docs.vatis.tech/api-reference/usage/stream-usage-resource-impl/stream-usage get /usage-service/api/v1/usage/streams/{streamId} Get the usage of all processors in a stream # Usage report Source: https://docs.vatis.tech/api-reference/usage/usage-report-resource-impl/usage-report get /usage-service/api/v1/usage/report Retrieve usage report for a given time interval # Create/update Source: https://docs.vatis.tech/api-reference/webhooks/webhook-endpoint-resource-impl/createupdate put /notification-service/api/v1/webhook-endpoints Creates or updates a webhook endpoint. # Delete Source: https://docs.vatis.tech/api-reference/webhooks/webhook-endpoint-resource-impl/delete delete /notification-service/api/v1/webhook-endpoints/{id} Deletes a webhook endpoint. # Find all Source: https://docs.vatis.tech/api-reference/webhooks/webhook-endpoint-resource-impl/find-all get /notification-service/api/v1/webhook-endpoints Finds all webhook endpoints of the current user. # Find by ID Source: https://docs.vatis.tech/api-reference/webhooks/webhook-endpoint-resource-impl/find-by-id get /notification-service/api/v1/webhook-endpoints/{id} Finds a webhook endpoint by id. # Get available event type Source: https://docs.vatis.tech/api-reference/webhooks/webhook-endpoint-resource-impl/get-available-event-type get /notification-service/api/v1/webhook-endpoints/supported-events Finds all supported events for webhook endpoints. # Toggle endpoint Source: https://docs.vatis.tech/api-reference/webhooks/webhook-endpoint-resource-impl/toggle-endpoint patch /notification-service/api/v1/webhook-endpoints/{id}/enabled/{enabled} Enables or disables a webhook endpoint. A disabled webhook won't be notified. # Ask Anything Source: https://docs.vatis.tech/audio-intelligence/ask-anything Create custom prompts for your content Configure your custom prompts using the following options: Specifies the custom prompt content for one of the `ask0`, `ask1`, ..., `askN` ask anything slots. When the content is specified, the prompt is considered activated. Otherwise, it is deactivated. Specifies the custom system prompt for one of the `ask0System`, `ask1System`, ..., `askNSystem` ask anything slots. Specifies the prompt id for one of the `ask0Id`, `ask1Id`, ..., `askNId` ask anything slots. The role of the prompt id is to identify the prompt in the responses. When unspecified, it will fallback on the index of the slot (e.g. `"0"`, `"1"`). Specifies the prompt response [JSON Schema](https://json-schema.org/overview/what-is-jsonschema) encoded as a string for one of the `ask0Format`, `ask1Format`, ..., `askNFormat` ask anything slots. When unspecified, the response not be structured in any particular way. When specified, the response will be a JSON object encoded as a string. ## Usage Currently, there are up to 3 ask anything slots available.
For using the ask anything slots, you can specify the prompts as query parameters in the request URL, or using a configuration message on the WebSocket connection. Here we'll create to custom prompts about the processed phone call: 1. `What was the client intent?` 2. `Was the client issue solved?` ```bash curl -X 'POST' \ 'https://http-gateway.vatis.tech/http-gateway/api/v1/upload?streamConfigurationTemplateId=668115d123bca7e3509723d4&ask0=What%20was%20the%20client%20intent%3F&ask1=Was%20the%20client%20issue%20solved%3F&persist=true' \ -H 'accept: application/json' \ -H 'Authorization: Basic ' \ -H 'Content-Type: application/octet-stream' \ --data-binary '@test-phone-call.wav' ``` When the prompts exceed the URL length limit, the alternative is to transmit the prompts over a WebSocket connection using a configuration message. ``` wss://ws-gateway.vatis.tech/ws-gateway/api/v1?streamConfigurationTemplateId=668115d123bca7e3509723d4&persist=true&egress=false&configurationMessage=true ``` Send this message as the first message after the connection is established: ```json { "type": "CONFIGURATION", "patches": { "ask0": "What was the client intent?", "ask1": "Was the client issue solved?" } } ``` ## Response ```json { ... "askAnything": { "0": { "promptId": "0", "content": "The client's intent was to sign up for a Wi-Fi service with ***, provide the necessary personal and address information, select a connection speed, and schedule an installation appointment." }, "1": { "promptId": "1", "content": "Yes, the client's issue was solved. George Washington successfully signed up for the Wi-Fi service, provided the necessary information, and scheduled an installation appointment for a convenient date and time. The representative also explained the costs and payment process." } } } ``` ## System Prompt Each ask-anything prompt can receive an optional system prompt alongside the custom prompt. The system prompt can be used to modify the LLM behavior or to provide additional context to the user prompt. The system prompt can be specified using the `ask0System`, `ask1System`, etc. query parameters. ## Prompt Id By default, each ask-anything prompt will be assigned with an ID corresponding to the prompt index. To override this behavior, you can specify the prompt ID using the `ask0Id`, `ask1Id`, etc. query parameters. For example, given the following prompt id values: `ask0Id=client_intent&ask1Id=issue_solved` The response will be: ```json { ... "askAnything": { "client_intent": { "promptId": "client_intent", "content": "The client's intent was to sign up for a Wi-Fi service with ***, provide the necessary personal and address information, select a connection speed, and schedule an installation appointment." }, "issue_solved": { "promptId": "issue_solved", "content": "Yes, the client's issue was solved. George Washington successfully signed up for the Wi-Fi service, provided the necessary information, and scheduled an installation appointment for a convenient date and time. The representative also explained the costs and payment process." } } } ``` ## Response format The generated response for each ask-anything prompt will have no particular structure. For the scenarios where the response should be structured in a predefined way, we can use the response format feature to specify a [JSON Schema](https://json-schema.org/overview/what-is-jsonschema) to parse the response against. To activate the response format feature, we need to specify the `ask0Format`, `ask1Format`, etc. query parameters having the JSON Schema value encoded as string. For example, we'll take the following prompt: `Extract the client identification details, the requested service and any relevant information to the requested service` And the following JSON Schema: ```json { "$defs": { "ClientIdentificationData": { "properties": { "name": { "title": "Name", "type": "string" }, "phone_number": { "title": "Phone Number", "type": "string" }, "date_of_birth": { "title": "Date Of Birth", "type": "string" } }, "required": [ "name", "phone_number", "date_of_birth" ], "title": "ClientIdentificationData", "type": "object" } }, "properties": { "client_identification": { "$ref": "#/$defs/ClientIdentificationData" }, "requested_service": { "enum": [ "WiFi", "GSM", "Billing" ], "title": "Requested Service", "type": "string" } }, "required": [ "client_identification", "requested_service" ], "title": "ClientRequest", "type": "object" } ``` The response will be: ```json { ... "askAnything": { "0": { "promptId": "0", "content": "{\"client_identification\":{\"name\":\"George Washington\",\"phone_number\":\"414-2**-****\",\"date_of_birth\":\"July *, 19**\"},\"requested_service\":\"WiFi\"}" } } } ``` By parsing the JSON encoded inside the string response we can get ```json { "client_identification": { "name": "George Washington", "phone_number": "414-***-****", "date_of_birth": "July **, 19**" }, "requested_service": "WiFi" } ``` The PII data will be explicitly displayed unless specified otherwise. ### Limitations * No default values are supported. * No arbitrary objects are allowed. All the required values must be specified. # Sentiment Analysis Source: https://docs.vatis.tech/audio-intelligence/sentiment-analysis Perform sentiment analysis over your content Enable sentiment analysis with the following configuration: Perform sentiment analysis on the upstream content. ## Pre-recorded ### Usage ```bash curl -X 'POST' \ 'https://http-gateway.vatis.tech/http-gateway/api/v1/upload?streamConfigurationTemplateId=668115d123bca7e3509723d4&sentimentAnalysis=true&persist=true' \ -H 'accept: application/json' \ -H 'Authorization: Basic ' \ -H 'Content-Type: application/octet-stream' \ --data-binary '@test.wav' ``` ### Mono audio ```json { ... "sentimentAnalysis": { "segments": [ { "text": " Good afternoon. My name is Aisha. Thank you for calling *** today. How may I be of assistance?", "sentiment": "positive", "startTime": 820, "endTime": 6120, "score": 0.9 }, { "text": " Hi, Aisha. Well, I want to sign up for the Wi-Fi service.", "sentiment": "positive", "startTime": 7660, "endTime": 13460, "score": 0.5 }, ... ], "summary": { "negativeCount": 2, "positiveCount": 21, "neutralCount": 31, "averageScore": 0.24444444444444446, "sentiment": "neutral" } } } ``` ### Stereo audio ```json { ... "sentimentAnalysis": { "segments": [ { "text": " Good afternoon. My name is Aisha. Thank you for calling *** today. How may I be of assistance?", "sentiment": "positive", "channel": 0, "startTime": 1010, "endTime": 6130, "score": 0.9 }, { "text": " Hi, Aisha. Well, I want to sign up for the Wi-Fi service.", "sentiment": "positive", "channel": 1, "startTime": 7660, "endTime": 24180, "score": 0.5 }, ... ], "summary": { "channels": [ { "channel": 0, "negativeCount": 0, "positiveCount": 17, "neutralCount": 11, "averageScore": 0.3642857142857143, "sentiment": "positive" }, { "channel": 1, "negativeCount": 1, "positiveCount": 10, "neutralCount": 17, "averageScore": 0.22142857142857145, "sentiment": "neutral" } ], "negativeCount": 1, "positiveCount": 27, "neutralCount": 28, "averageScore": 0.2928571428571428, "sentiment": "neutral" } } } ``` ## Real-time The sentiment analysis results can be consumed in real-time. Each sentiment analysis message will contain either an `utterance sentiment analysis` or a `summary sentiment analysis`. ### Utterance sentiment analysis The sentiment analysis will be performed for each utterance in the conversation. ```json { "promptId": "sentimentAnalysis", "sequenceId": 0, "sentimentAnalysis": [ { "text": " Good afternoon. My name is Aisha. Thank you for calling Verizon today. How may I be of assistance?", "sentiment": "positive", "channel": 0, "startTime": 0, "endTime": 7679, "score": 0.8 } ] } ``` ### Summary sentiment analysis After all the utterances have been processed, a summary sentiment analysis will be provided. ```json { "promptId": "sentimentAnalysis", "sequenceId": 9, "sentimentAnalysisSummary": { "channels": [ { "channel": 1, "negativeCount": 0, "positiveCount": 1, "neutralCount": 3, "averageScore": 0.2, "sentiment": "neutral" }, { "channel": 0, "negativeCount": 0, "positiveCount": 4, "neutralCount": 1, "averageScore": 0.52, "sentiment": "positive" } ], "negativeCount": 0, "positiveCount": 5, "neutralCount": 4, "averageScore": 0.3777777777777778, "sentiment": "positive" } } ``` # Summarization Source: https://docs.vatis.tech/audio-intelligence/summarization Extract the essentials from your content Configure the summary with the following options: Create a summary based on the upstream content. Summary length. Options are: `brief` or `detailed`. Summary tone. Options are: `conversational` or `informative`. Summary structure. Options are: `paragraphs` or `bullet_points`. ## Usage ```bash curl -X 'POST' \ 'https://http-gateway.vatis.tech/http-gateway/api/v1/upload?streamConfigurationTemplateId=668115d123bca7e3509723d4&summary=true&summaryTone=informative&persist=true' \ -H 'accept: application/json' \ -H 'Authorization: Basic ' \ -H 'Content-Type: application/octet-stream' \ --data-binary '@test.wav' ``` ## Export Response ```json { ... "summary": { "content": "A customer named George Washington contacted *** to sign up for Wi-Fi service. During the call, he provided his phone number..." } } ``` # Get API access Source: https://docs.vatis.tech/get-started/get-api-access Get the API key to gain access to the Vatis Streams API Create an account on the Vatis Tech cloud platform. You can sign up [here](https://vatis.tech/app). Once you have signed up, you can get the API key from the [API Dashboard](https://vatis.tech/app/playground/transcribe). Try out our API using the [API Playground](https://vatis.tech/app/playground/transcribe). # Configuration patches Source: https://docs.vatis.tech/infrastructure/configuration-patches Customizing stream execution with configuration patches ## Overview Each stream is composed by a DAG of processors though which the data is processed. Each processor has a set of properties that can be configured to customize its behavior. Those properties are defined inside a stream configuration template, and it can look similar to this: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.llm.LlmPropertiesDto", "properties": { "summary": { "enabled": true, "flushInterval": "300", "properties": { "tone": "Conversational", "length": "Brief", "structure": "Paragraphs" } } }, ... } ] } ``` The system follows a **convention over configuration** approach, where the default values are defined in the processor implementation. Generally, the default values are good enough for most of the cases, but sometimes you may need to customize the behavior of a processor. For example, you may want to change the tone of the summary generated by the LLM processor from `Conversational` to `Formal`. This can be done by creating a configuration patch that overrides the default value of the `tone` property. ## Configuration patches A configuration patch is a JSON Patch that respects the [RFC 6902](https://tools.ietf.org/html/rfc6902) standard, with some imposed limitations. The limitations are: * the only supported operations are `add`, `replace`, and `remove` * it can only apply to the `properties` object of a processor * the added/replaced values can be either a primitive value or an array of primitive values The accepted primitive values are: * string * number * boolean * null For example, the configuration patch that changes the tone of the summary generated by the LLM processor from `Conversational` to `Formal` looks like this: ```json [ { "op": "replace", "path": "/processors/0/properties/summary/properties/tone", "value": "Formal" } ] ``` The json paths can be also expressed using `.`. For example, `properties.0.properties.tone`, `properties/0/properties/tone` and `/properties/0/properties/tone` are all equivalent paths. ## Specifying patches The JSON Patch format proposed in the [RFC 6902](https://tools.ietf.org/html/rfc6902) standard is not always suitable for specifying configuration patches. For this reason, the system allows specifying configuration patches as `query parameters` in the URL (all gateways) or using a configuration message (`WS Gateway` only). ### Query parameters The query parameters are specified in the URL of the request, and they are used to specify the configuration patches that should be applied to the stream configuration template. Every patch query parameter can be explicitly marked as a patch by using the `patches.` prefix. If the prefix is not specified, all undocumented query parameters are considered as patches. For example, the equivalent of this JSON Patch: ```json [ { "op": "replace", "path": "/processors/0/properties/summary/properties/tone", "value": "Formal" } ] ``` is the following query parameter: ``` https://gateway.vatis.tech/url?patches.processors.0.properties.summary.properties.tone=Formal ``` or even shorter: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.tone=Formal ``` #### Operation By default, the operation is `replace`. To use the `add` operation, prefix the patch value with `+`. For example, to add the `language` property with the value `en`, use the following query parameter: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.language=+en ``` The `replace` operation will behave as the `add` operation if the property does not exist. So, the equivalent of the previous query parameter is: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.language=en ``` To use the `remove` operation, set the patch value to `-`. For example, to remove the `tone` property, use the following query parameter: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.tone=- ``` To escape the `+` and `-` characters, use the `\` character. For example, to set the `tone` property to `+Formal`, use the following query parameter: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.tone=\+Formal ``` In most of the cases, the `replace` operation is enough, and you don't need to specify it explicitly. ### Configuration message The configuration message is a WebSocket message sent by the client as an initial message to the `WS Gateway`, with the following structure: ```json { "type": "CONFIGURATION", "patches": { "": "" } } ``` The rules of the configuration patches are the same as for the query parameters. For example, the configuration message that changes the tone of the summary generated by the LLM processor from `Conversational` to `Formal` looks like this: ```json { "type": "CONFIGURATION", "patches": { "/processors/0/properties/summary/properties/tone": "Formal" } } ``` or using the `.` notation: ```json { "type": "CONFIGURATION", "patches": { "processors.0.properties.summary.properties.tone": "Formal" } } ``` A configuration message can contain as many patches as needed, and without any (reasonable) length limitation. The configuration message can be used alongside the query parameters, and the patches from the configuration message will overwrite the patches from the query parameters. Use the configuration message only when you need to specify a longer value that would not fit in the URL. ## Simplifying paths ### Processor index Each patch path must contain the index of the processor to which the patch should be applied. This may be problematic if the processors order is changed, and the indexes are not updated accordingly. This can be avoided by using the processor ID instead of the index. For example, the following patch: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.language=en ``` can be rewritten as: ``` https://gateway.vatis.tech/url?processors.llm.properties.summary.properties.language=en ``` ### Path alias Each processor can specify a path alias that can be used to simplify the patch path. Given the following stream configuration template: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.llm.LlmPropertiesDto", "properties": { "summary": { "enabled": true, "flushInterval": "300", "properties": { "tone": "Conversational", "length": "Brief", "structure": "Paragraphs" } } }, "patchAliases": { "summary": "properties/summary/enabled", "summary_tone": "properties/summary/properties/tone", "summary_length": "properties/summary/properties/length", "summary_structure": "properties/summary/properties/structure" }, ... } ] } ``` The following patch: ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.tone=Formal ``` can be rewritten as: ``` https://gateway.vatis.tech/url?summary_tone=Formal ``` ### The equivalence chain To better understand, we'll take the following example, and we'll rewrite it from the most complex to the simplest form. Given the following stream configuration template: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.llm.LlmPropertiesDto", "properties": { "summary": { "enabled": true, "flushInterval": "300", "properties": { "tone": "Conversational", "length": "Brief", "structure": "Paragraphs" } } }, "patchAliases": { "summary_tone": "properties/summary/properties/tone", "summary_language": "properties/summary/properties/language" }, ... } ] } ``` And the following patch: ```json [ { "op": "replace", "path": "/processors/0/properties/summary/properties/tone", "value": "Formal" }, { "op": "add", "path": "/processors/0/properties/summary/properties/language", "value": "en" } ] ``` The most complex form of the patch is: ``` https://gateway.vatis.tech/url?patches.processors.0.properties.summary.properties.tone=Formal&patches.processors.0.properties.summary.properties.language=+en ``` then we'll infer the redundant `patches.` prefix ``` https://gateway.vatis.tech/url?processors.0.properties.summary.properties.tone=Formal&processors.0.properties.summary.properties.language=+en ``` then we'll substitute the processor index with the processor ID ``` https://gateway.vatis.tech/url?processors.llm.properties.summary.properties.tone=Formal&processors.llm.properties.summary.properties.language=+en ``` then we'll replace the `add` operation for `language` with `replace` ``` https://gateway.vatis.tech/url?processors.llm.properties.summary.properties.tone=Formal&processors.llm.properties.summary.properties.language=en ``` then we'll use the path aliases for `tone` and `language` ``` https://gateway.vatis.tech/url?summary_tone=Formal&summary_language=en ``` ## Examples Given: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.llm.LlmPropertiesDto", "properties": { "summary": { "enabled": false, "flushInterval": "300", "properties": { "tone": "Conversational", "length": "Brief", "structure": "Paragraphs" } } }, "patchAliases": { "summary": "properties/summary/enabled" }, ... } ] } ``` To enable the summary, use the following query parameter: ``` https://gateway.vatis.tech/url?summary=true ``` Given: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.llm.LlmPropertiesDto", "properties": { "summary": { "enabled": false, "flushInterval": "300", "properties": { "tone": "Conversational", "length": "Brief", "structure": "Paragraphs" } } }, "patchAliases": { "summary_language": "properties/summary/properties/language" }, ... } ] } ``` To add the summary language, use the following query parameter: ``` https://gateway.vatis.tech/url?summary_language=en ``` Given: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.whispergpu.WhisperGpuProcessorPropertiesDto", "properties": { "allowedLanguages": null }, "patchAliases": { "allowed_languages": "properties/allowedLanguages" }, ... } ] } ``` To set the allowed languages to `["en", "fr"]`, use the following query parameter: ``` https://gateway.vatis.tech/url?allowed_languages=en&allowed_languages=fr ``` Given: ```json { "_id": "674c1f1ea3fc806ecb01df55", "processors": [ { "_id": "llm", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.llm.LlmPropertiesDto", "properties": { "summary": { "enabled": false, "flushInterval": "300", "properties": { "tone": "Conversational", "length": "Brief", "structure": "Paragraphs" } } }, "patchAliases": { "summary": "properties/summary/enabled", "summary_tone": "properties/summary/properties/tone" }, ... } ] } ``` To enable the summary and set the tone to `Formal`, use the following configuration message: ```json { "type": "CONFIGURATION", "patches": { "summary": "true", "summary_tone": "Formal" } } ``` # Data retention Source: https://docs.vatis.tech/infrastructure/data-retention Data retention policy of the Vatis Streams API ## Overview The streams created using the Vatis Streams API falls under one of the following categories: * **ephemeral**: Streams that are created with a retention period of 0 seconds. These stream results are not persisted and are deleted as soon as the last subscriber disconnects. * **persistent**: Streams that retain the result for a limited period of time. ## Ephemeral streams This is the default behavior of a stream. It's ideal for real-time usage and mitigates any data privacy concerns by removing all the data in the stream as soon as the last subscriber disconnects, or in up 60 seconds if the data is not consumed. ## Persistent streams The persistent streams can be used for non-real-time use cases (e.g. file transcription) when the results must be exported all at once. For this kind of stream, the data is persisted for about 3 hours before being deleted. This time may increase with up to 1 hour depending on the load on the system. To configure a stream as persistent, use the `persist=true` flag at creation time. The API also provides the means to selectively persist only some of the results. Please refer to the [OpenAPI specification](https://http-gateway.vatis.tech/swagger-ui/index.html) for more details. # Export results Source: https://docs.vatis.tech/infrastructure/diagrams/export-results Overview of the possible methods to export results from a batch job This section applies only to batch jobs # Webhook notification This is the recommended flow to export results as it does not require constant requests to check stream states, and assures the delivery using the exponential backoff retry mechanism. This method requires an accessible server to receive the notifications. ```mermaid sequenceDiagram participant U as Client participant NS as Notification Service participant SS as Stream Service participant G as Gateway participant ES as Export Service rect rgb(82, 82, 82) note over U, NS: Webhook registration happens only once U->>+NS: register webhook endpoint NS->>-U: receive register confirmation end U->>G: upload data G->>SS: create stream SS->>NS: push event loop Retry with backoff NS->>+U: notify webhook U-x-NS: return error status or fail to respond in time end NS->>+U: notify webhook U->>-NS: return 200 status code U->>+ES: export results ES->>-U: return exported results ``` # Polling Use this method for developing and testing, or when exposing an HTTP server is not possible. ```mermaid sequenceDiagram participant U as Client participant SS as Stream Service participant G as Gateway participant ES as Export Service U->>G: upload data G->>SS: create stream loop Poll stream status U->>+SS: check stream status SS-x-U: stream no ready end U->>+SS: check stream status SS->>-U: stream completed U->>+ES: export results ES->>-U: return exported results ``` # System overview Source: https://docs.vatis.tech/infrastructure/diagrams/system-overview Overview of the main flows and components of the system ```mermaid flowchart TB gateway("HTTP Gateway") streamService("Stream Service") streamConfigurationService("Stream Configuration Service") egressService("Egress Service") exportService("Export Service") sourceStreamingTopic(["Source streaming topic"]) destinationStreamingTopic(["Destination streaming topic"]) processor("Processor") clientInput((("Input data"))) clientLiveOutput((("Live egress"))) clientExportOutput((("Export output"))) subgraph processingBlock["Processing block"] direction RL sourceStreamingTopic-->|4. consume|processor processor-->|5. output results|destinationStreamingTopic end clientInput==>|1. send bytes|gateway gateway-->|2. create stream|streamService streamService-->|2.1. fetch stream configuration template|streamConfigurationService streamConfigurationService-->|2.2. return stream configuration template|streamService streamService-->|2.3. return stream configuration|gateway gateway-->|3. publish bytes|sourceStreamingTopic egressService-->|6.1. consume results|destinationStreamingTopic clientLiveOutput-->|6.2. receive live results|egressService exportService-->|7.1. retrieve results|egressService clientExportOutput-->|7.2. export results|exportService ``` # Stream templates Source: https://docs.vatis.tech/infrastructure/stream-templates Overview of the stream configuration templates ## Introduction In Vatis Streams engine, the first-class entity is a *stream*. A stream is a DAG of processors. This DAG of processors alongside with the configuration of each processor is stored in a **stream configuration template**. Each stream created using the Vatis Streams API is based on a stream configuration template, that can be patched to modify processors configuration. ## Stream configuration template A stream configuration template can be (optionally) patched and retrieved using the [**Patch by id endpoint**](/api-reference/stream-configuration/stream-configuration-template-resource-impl/patch-by-id) An example of a stream configuration template is shown below: ```json { "id": "65f46430c6d8985974ff9c9d", "name": "Ping", "description": "Simple pipeline for testing stream latency", "dataSourceSchema": "bytes", "processors": [ { "id": "echo", "name": "echo", "description": "Echo operation", "processorDeclaration": { "id": "echo", "displayName": "Echo", "description": "Echo processor. Returns the same message it receives.", "clusterDomainNameTemplate": "echo-${REPLICA}.echo-headless.stream-processors.svc.cluster.local", "podsDiscoveryClusterDomainName": "echo-headless.stream-processors.svc.cluster.local", "revision": "2024-02-06", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.NoPropertiesDto", "inputSchemas": [ "bytes" ], "outputSchema": "bytes", "features": { "support": [], "require": [], "implement": [], "requireSupport": [] }, "operationType": "NO_OPERATION" }, "previousProcessorId": null, "propertiesSchema": "tech.vatis.schema.stream.processor.properties.NoPropertiesDto", "properties": {}, "destinationTopicMessageHeaders": {}, "destinationTopicHeaders": { "X-Vat-Topic-Accept-Frame-Type": "final" }, "sourceSubscriptionHeaders": { "X-Vat-Sub-Accept-Frame-Type": "final" }, "patchAliases": {}, "egress": { "persist": false, "sink": false, "tags": [] } } ], "patchAliases": {} } ``` This stream configuration template can produce a stream similar to the one shown below: ```json { "streamId": "20d36912-f746-4f45-8e68-d537fc1ff57f", "name": "Stream jokidx", "groupId": "20d36912-f746-4f45-8e68-d537fc1ff57f", "configuration": { "streamConfigurationTemplateId": "65f46430c6d8985974ff9c9d", "dataSource": { "topic": "persistent://vatis-streams/data-sources/4c43a454-32b4-4ef4-baa9-3442f5fecc90", "messageSchema": "bytes", "connectionOptions": { "X-Vat-Topic-Conn-Close-On-Disconnect": "true" }, "headers": { "X-Vat-Topic-Accept-Frame-Type": "final" }, "messageHeaders": { "X-Vat-Stream-Frame-Type": "final", "X-Vat-Stream-Processor-Id": "gateway" }, "subscriptions": { "echo": { "subscription": "echo-ZlejK", "topic": "persistent://vatis-streams/data-sources/4c43a454-32b4-4ef4-baa9-3442f5fecc90", "messageSchema": "bytes", "connectionOptions": {}, "headers": { "X-Vat-Sub-Accept-Frame-Type": "final" } } } }, "dataSinks": { "echo": { "topic": "persistent://vatis-streams/persistent-data-sinks/f8eeb155-d496-4746-b949-94ae05426544", "messageSchema": "bytes", "connectionOptions": {}, "headers": { "X-Vat-Topic-Accept-Frame-Type": "final" }, "messageHeaders": { "X-Vat-Stream-Egress-Tags": "echo,main", "X-Vat-Stream-Id": "20d36912-f746-4f45-8e68-d537fc1ff57f", "X-Vat-Stream-Group-Id": "20d36912-f746-4f45-8e68-d537fc1ff57f", "X-Vat-Stream-Schema": "bytes", "X-Vat-Stream-Processor-Id": "echo" }, "subscriptions": {} } }, "processors": [ { "id": "echo", "source": { "subscription": "echo-ZlejK", "topic": "persistent://vatis-streams/data-sources/4c43a454-32b4-4ef4-baa9-3442f5fecc90", "messageSchema": "bytes", "connectionOptions": {}, "headers": { "X-Vat-Sub-Accept-Frame-Type": "final" } }, "destination": { "topic": "persistent://vatis-streams/persistent-data-sinks/f8eeb155-d496-4746-b949-94ae05426544", "messageSchema": "bytes", "connectionOptions": {}, "headers": { "X-Vat-Topic-Accept-Frame-Type": "final" }, "messageHeaders": { "X-Vat-Stream-Egress-Tags": "echo,main", "X-Vat-Stream-Id": "20d36912-f746-4f45-8e68-d537fc1ff57f", "X-Vat-Stream-Group-Id": "20d36912-f746-4f45-8e68-d537fc1ff57f", "X-Vat-Stream-Schema": "bytes", "X-Vat-Stream-Processor-Id": "echo" }, "subscriptions": {} }, "clusterDomainName": "echo-0.echo-headless.stream-processors.svc.cluster.local", "podsDiscoveryClusterDomainName": "echo-headless.stream-processors.svc.cluster.local", "propertiesSchema": "tech.vatis.schema.stream.processor.properties.NoPropertiesDto", "properties": {}, "egress": { "persist": true, "sink": true, "tags": [ "main", "echo" ] } } ] }, "createdTimestamp": "2024-12-12T18:47:06.865Z", "creatorId": "d710a067-daf3-460d-9e60-01d0bb8d10c4", "groupCreatorId": "d710a067-daf3-460d-9e60-01d0bb8d10c4", "state": "READY", "stateDescription": null, "finalizedTimestamp": null } ``` The Vatis Streams API provides a set of pre-defined stream configuration templates that can be used out-of-the-box for use-cases like Speech-to-Text, Audio Intelligence, Real-time transcoding, etc. ## Streams When a stream is created, it requires a stream configuration template id. This can be specified using the `streamConfigurationTemplateId` query parameter set in the connection URL. # Inspect errors Source: https://docs.vatis.tech/infrastructure/streams/inspect-errors Debug a failed stream by inspecting its errors ## Overview A stream error is a signal that something went wrong in the stream. It can occur in one of the following stream stages: * during stream creation * during stream processing In this guide, you will learn how to inspect errors in a stream based on the stage it occurred. ## Stream creation errors A stream creation error is an error that can be determined ahead of time, before the stream starts processing. It can occur due to various reasons, such as: * invalid stream configuration * maximum number of concurrent streams reached * insufficient compute capacity * authn or authz errors The stream creation error may occur only in the upload phase, and it will result in a non-2xx HTTP status code. The response body will be a standard [Error Response](/api-reference/schemas/error/error-response) JSON object, which can look like this: ```json { "statusCode": 400, "title": "Invalid stream configuration", "message": "Forbidden patch: /langs", "internalErrorName": "STREAM_CONFIGURATION_BAD_PATCH", "nestedErrors": [] } ``` ## Stream processing errors A stream processing error is an asynchronous error that occurs during the stream processing phase due to request data processing problems. It can occur due to various reasons, such as: * invalid or missing request data * unsupported payload type * payload too large An asynchronous error will cause the stream to enter in the `FAILED` state, and it can be identified either by regularly polling the [stream state](/api-reference/streams/stream-resource-impl/find-by-id) or receiving a `stream.failed` webhook notification. The error details can be extracted from the [stream components state](/api-reference/streams/stream-resource-impl/get-components). The response can look like this: ```json { "streamId": "46df931a-3622-4c39-80fe-70d636e99ba5", "groupId": "46df931a-3622-4c39-80fe-70d636e99ba5", "state": "FAILED", "stateDescription": null, "stateChangedTimestamp": "2025-02-19T04:42:32.344Z", "gateway": { "state": "CLOSED", "stateChangedTimestamp": "2025-02-19T04:42:28.037Z" }, "processors": [ { "processorId": "transcriber", "state": "ERROR", "stateChangedTimestamp": "2025-02-19T04:42:32.328Z", "stateDescription": "External close signal received" }, { "processorId": "diarization", "state": "ERROR", "stateChangedTimestamp": "2025-02-19T04:42:32.298Z", "stateDescription": "[InternalErrorName.GENERAL_INTERNAL_ERROR] JobFailedException: Job 5fb5614f-8959-409f-931f-3f9a4f233130-e1 failed with status FAILED: [Errno 1094995529] Invalid data found when processing input: ..." }, { "processorId": "llm", "state": "COMPLETED", "stateChangedTimestamp": "2025-02-19T04:42:28.027Z", "stateDescription": "Stream has no prompt enabled" } ] } ``` Here we can see that the `transcriber` and `diarization` processors are in the `ERROR` state. The `stateDescription` field provides additional information about the error. The `External close signal received` message indicates that the processor was closed by either a cancel action from the user or from an automatic cancel due to other processor failure in the same pipeline. # Export Source: https://docs.vatis.tech/integration/export Export results from one or multiple streams in various formats ## Overview The Vatis Streams API is designed to egress the results from one or multiple streams in real-time as JSON events or as bytes.

This means the client will receive the results in the fastest way possible, but it also means that the client needs to reconstruct the final results based on the received events.
In some scenarios, the client will not need the data in real-time, but rather in a more structured format.

For these cases, the Vatis Streams API provides an **export functionality** that handles this layer of complexity and allows the client to export the results from one or multiple streams in various formats. ## Formats Currently, the single format supported is `JSON`. The exact structure of the JSON response is determined by the aggregated event type from the stream(s). Please refer to the [export OpenAPI specification](https://export-service.vatis.tech/swagger-ui/index.html) for more details. ## When to export? Although the export functionality is available at any time after the stream was created, it is recommended to export the results only after the stream has finished. This is because the export functionality will return the results in a single response, so the blocking connection may time out if it's long-running stream. To find out when a stream is completed, either us the [webhook integration](/integration/webhooks) or stream status polling. Perform the export before the stream expires, as describe in [data retention](/infrastructure/data-retention) ## Considerations * only non-raw results can be used as part of the export functionality * the export functionality works only with [persistent streams](/infrastructure/data-retention) # Webhooks Source: https://docs.vatis.tech/integration/webhooks Listen to events on your resources with webhooks. ## Overview When integrating the Vatis Streams API you may need to listen to events on your resources, so your application can react accordingly. To do this, you can register a webhook endpoint containing the URL where you want to receive the events and the type of events the endpoint is listening to. When an event is triggered, a `POST` request will be sent to all the registered endpoints with the event data. ## Setup Manage your webhooks through the [API Dashboard](https://vatis.tech/app/playground/webhooks). ## Webhook structure The webhook endpoint you can define will have the following structure: ```json { "id": "", "url": "", "events": [ "" ], "enabled": true, "description": "" } ``` | Property | Description | | ------------- | ----------------------------------------------------------------------------------------------------------------------- | | `id` | The webhook endpoint identifier | | `url` | The URL where the events will be sent. Accepted protocols: `HTTP`, `HTTPS` | | `events` | The list of event types the endpoint is listening to. Check the avaiable event types [here](#event-types) | | `enabled` | Indicates if the webhook is enabled. You can disable an endpoint to temporarily stop receiving requests to the endpoint | | `description` | An optional description of the webhook | Local IP addresses and loopback interfaces are not allowed in the `url` ## Event structure The webhook event you'll receive will have the following structure: ```json { "id": "", "type": "", "webhookEndpointId": "", "timestamp": "", "payloadSchema": "", "payload": "" } ``` | Property | Description | | ------------------- | ----------------------------------------------------------------------------------- | | `id` | The event identifier | | `type` | The event type. Check the avaiable event types [here](#event-types) | | `webhookEndpointId` | The webhook endpoint identifier | | `timestamp` | The event timestamp in milliseconds since epoch. Use this to prevent replay attacks | | `payloadSchema` | The fully qualified name of the payload schema | | `payload` | The event payload | ## Event types | Event type | Supports dynamic webhooks | Description | | :--------------------- | :-----------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `stream.ready` | yes | The stream has just been created and is ready to receive data | | `stream.completed` | yes | The stream completed successfully | | `stream.failed` | yes | The stream failed | | `stream.expired` | yes | The stream storage time expired and it was deleted | | `group.created` | yes | A new group has been created | | `group.completed` | yes | All the streams in the group completed successfully. This event will be emitted again if a new stream joins the group and completes | | `group.failed` | yes | All the streams in the group finished and at least one stream failed. This event will be emitted again if a new stream joins the group and fails | | `group.expired` | yes | The group storage time expired and it was deleted. A group will expire only after all the streams in the group had expired | | `group.stream-joined` | yes | A new stream has joined the group | | `gateway.connected` | no | A client connected to the stream gateway | | `gateway.disconnected` | no | The client disconnected from the stream gateway | | `gateway.closed` | no | The gateway of the stream is permanently closed | | `gateway.error ` | no | The gateway of the stream is permanently closed due to an error | | `processor.running` | no | The stream processor has been assigned to stream and it is running | | `processor.completed` | no | The stream processor has been completed successfully | | `processor.error` | no | The stream processor has failed | ## Source IPs To make sure your server is able to receive the events, you can **whitelist** the following IP addresses: * `Europe`: `52.59.67.134` ## Redelivery If the server does not respond with a `2xx` status code, the event redelivery will be retried for the next three hours with an exponential backoff strategy. ## Development For experimenting the webhook integration on a local environment, you can create the setup described below. ```bash curl -s https://ngrok-agent.s3.amazonaws.com/ngrok.asc | sudo tee /etc/apt/trusted.gpg.d/ngrok.asc >/dev/null && echo "deb https://ngrok-agent.s3.amazonaws.com buster main" | sudo tee /etc/apt/sources.list.d/ngrok.list && sudo apt update && sudo apt install ngrok ``` ```bash snap install ngrok ``` ```bash brew install ngrok/ngrok/ngrok ``` ```bash choco install ngrok ``` Alternatively, you can download the executable from the [official website](https://ngrok.com/download) ```bash apt install nginx ``` ```bash brew install nginx ``` Download the installer from the [official website](https://nginx.org/en/download.html) ```bash cat < /etc/nginx/conf.d/dev-webhook.conf server { listen 8081; server_name localhost; location /200 { add_header Content-Type text/plain; return 200 "200 - OK"; } location /400 { add_header Content-Type text/plain; return 400 "400 - ERROR"; } location /500 { add_header Content-Type text/plain; return 500 "500 - SERVER ERROR"; } } ``` ```bash cat < /opt/homebrew/etc/nginx/servers/dev-webhook.conf server { listen 8081; server_name localhost; location /200 { add_header Content-Type text/plain; return 200 "200 - OK"; } location /400 { add_header Content-Type text/plain; return 400 "400 - ERROR"; } location /500 { add_header Content-Type text/plain; return 500 "500 - SERVER ERROR"; } } ``` ```bash nginx ngrok http 8081 ``` Create or update the webhook endpoint URL with the temporary URL provided by ngrok. Choose one of the following as URL paths, based on the test you want to perform: * `/200` * `/400` * `/500` Open the Ngrok dashboard at [http://localhost:4040](http://localhost:4040) to monitor the requests. Create a new stream or group to trigger the events. ## Considerations 1. A user can define up to 20 webhook endpoints 2. The same event may be sent multiple times to the same endpoint 3. The order of the events is not guaranteed ## Dynamic webhooks A dynamic webhook is a webhook defined on a resource basis. In contrast to a standard webhook that is defined once and can be triggered by any resource (group, stream, gateway, etc.) based on the event key, a dynamic webhook is associated with a specific resource and it can be triggered only by that resource. The main advantage of a dynamic webhook is the ability to modify the endpoint URL for each created stream. For example, we can include a unique identifier in the endpoint URL that changes for each created stream. ### All gateways For each available gateway, a dynamic webhook can be defined as a query parameter that follows this general syntax: `webhook[.RESOURCE[.STATE]]=` For example: * `webhook.stream.completed=https://mydomain.com/success` will create a dynamic webhook the receives the `stream.completed` event at the `https://mydomain.com/success` URL * `webhook.stream.completed=https://mydomain.com/success&webhook.stream.failed=https://mydomain.com/fail` will create two dynamic webhooks, one that will be triggered by the `stream.completed` event at the `https://mydomain.com/success` URL, and the other that will receive the `stream.failed` event at the `https://mydomain.com/fail` URL * `webhook.stream.completed=https://mydomain.com/status&webhook.stream.failed=https://mydomain.com/status` will create a single dynamic webhook that will be triggered by both `stream.completed` and `stream.failed` events at the `https://mydomain.com/status` URL * `webhook.stream=https://mydomain.com/stream-event` is a wildcard dynamic webhook that be triggered by any stream-related event at the `https://mydomain.com/stream-event` URL * `webhook=https://mydomain.com/any-event` is a wildcard dynamic webhook that will be triggered by any event at the `https://mydomain.com/any-event` URL ### Websocket Gateway Additionally to the dynamic webhooks defined using query parameter, the `WebSocket Gateway` can receive the dynamic webhooks configuration using the [Configuration Message](/integration/websocket#configuration). The general form of the webhook configuration is as follows: ```json { "type": "CONFIGURATION", "webhook": { "https://mydomain.com/success": ["stream.completed"], "https://mydomain.com/fail": ["stream.failed"], "https://mydomain.com/status": ["stream.completed", "stream.failed"], "https://mydomain.com/stream-event": ["stream.*"], "https://mydomain.com/any-event": ["*"] } } ``` Please use either the query parameters or the configuration message for defining the dynamic webhooks. If both are specified, the behaviour is undefined. ### Limitations * Only `stream` and `group` resources can be used in dynamic webhooks * No more than 3 dynamic wehooks can be defined * The supported endpoint protocols are `http` and `https` # Websocket Source: https://docs.vatis.tech/integration/websocket Perform real-time operations with Vatis Streams websocket API ## Overview Websocket API comes as an alternative to the integration of the ingress (via `HTTP Gateway`) and the egress connection (via `Egress Service`) that combines the two in a single, easier to manage, connection. The connection is managed by the `WS Gateway` component and it can be used as a bot ingress and egress connection, or only as an ingress connection. The `Egress Service` can be used along side with the `WS Gateway` to retrieve the results of the websocket-initiated stream from multiple clients. ### Diagrams ```mermaid sequenceDiagram participant C as Client participant S as Server C->>S: Initiate stream C-->>S: Send configuration S->>C: Return stream metada loop Exchange messages C->>S: Audio data C->>S: Audio data S->>C: Response C->>S: Audio data S->>C: Response C-->>S: keep-alive C->>S: Audio data S->>C: Response end note over S,C: All client data sent C->>S: End of stream note over S,C: Wait for the last responses S->>C: Response C-->>S: keep-alive S->>C: End of stream S-->>C: Normal connection close ``` ## Authentication A client can authenticate to the websocket API by providing either a `Basic` or a `Bearer` token. The token can be placed in either the `Authorization` or `Sec-WebSocket-Protocol` headers. * `Authorization: Basic ` * `Authorization: Bearer ` ### Basic token The basic token is a base64 encoded string of the `username:password` pair. The `username` is the `client_id` and the `password` is the `client_secret`. ### Bearer token Generate a bearer token using the [authentication endpoint](/api-reference/commons/authenticate). Use this authentication method when the token will reach a front channel (e.g. website) ## Configuration The stream configuration options will be passed as query parameters to the websocket connection URL or using the configuration message. By default, no configuration message is expected, and sending one will result in an error. To enable the configuration message, set the configuration message query parameter in the connection URL, then send the configuration message after the connection is established. Learn about configuration patches [here](/infrastructure/configuration-patches). For more details, please check the [WS Gateway API Reference](/api-reference/introduction) and the properties of the stream configuration template you're planning to use. ## Stream metadata Right after the client connects, and attempt to create the stream is made. If successful, a `stream metadata` message will be sent to the client. Otherwise, an error will be emitted and the connection will be closed. > *Message schema*: [StreamMetadataMessageDto](https://schema.vatis.tech/swagger-ui/index.html#/) ```mermaid sequenceDiagram participant C as Client participant S as Server C->>S: Initiate stream S->>C: Error on stream creation S-->>C: Normal connection close ``` ## Responses The server will respond in one of the following formats based on the configured egress format: * `EVENTS`: wrap the processor response in a metadata JSON object * `RAW`: return the processor response as is, generally as a websocket binary message The default format is `EVENTS`, that will be suited for most of the use-cases. > *Message schema*: [ResponseMessageDto](https://schema.vatis.tech/swagger-ui/index.html#/) Use the `RAW` format only when a binary response is expected ## Timeouts Generally the client will continuously send messages to the server, but there are scenarios where the client will stay idle (e.g. waiting for a new chunk of data to send or waiting for the end of stream signal).
The websocket connection will be closed after **10 seconds of inactivity**. We define the period inactivity as the time elapsed since the last message was sent by the client. To prevent the connection to close, the client has two options: * send a `KeepAlive message` when the client becomes idle * send a `Ping message` to the server. This will trigger a `Pong message` from the server In this case the connection will become idle. We define the idle period as the time elapsed since the last non-keep-alive message was sent by the client. > *Message schema*: [KeepAliveMessageDto](https://schema.vatis.tech/swagger-ui/index.html#/) Idle connections will timeout after 30 minutes Timeout connections will be closed without any error message or signal Use the `ping-pong` mechanism if the library provides it. Set the ping interval to `5 seconds` ### Diagrams ```mermaid sequenceDiagram participant C as Client participant S as Server C->>S: Initiate stream S->>C: Return stream metada C->>+S: Data S-->S: Wait for new data Note right of S: 10 seconds of inactivity S-->-C: Timeout - sudden connection close ``` ```mermaid sequenceDiagram participant C as Client participant S as Server C->>S: Initiate stream S->>C: Return stream metada C->>+S: Data S-->S: Wait for new data C-->>S: keep-alive S-->S: Wait for new data C-->>S: keep-alive S-->S: Wait for new data Note right of S: 30 minutes since last sent data S-->-C: Timeout - sudden connection close ``` ```mermaid sequenceDiagram participant C as Client participant S as Server C-->S: initial messages C->>+S: End of stream S->>C: Response Note right of S: Inactivity S->>C: Response S-->-C: keep-alive S->>C: Response S->>C: End of stream S-->>C: Normal connection close ``` ## End of stream After the client has sent all the data, it must signal this by sending an `End of stream` message. If the client is waiting for all responses, it must wait for the `End of stream` message from the server. After sending the `End of stream` message, the server will immediately close the connection. > *Message schema*: [EndOfStreamMessageDto](https://schema.vatis.tech/swagger-ui/index.html#/) A client disconnect will trigger the end of stream signal The server will emit an End of Stream signal only if the websocket connection is also used as egress ### Diagrams ```mermaid sequenceDiagram participant C as Client participant S as Server C-->S: initial messages C->>S: End of stream S->>C: Response S->>C: Response Note over S,C: All responses sent S->>C: End of stream S-->>C: Close connection ``` ## Error handling The server will emit an error message if the client sends an invalid message or if the server encounters an error while processing the message. The connection will be closed by the server immediately after sending the error message. > *Message schema*: [ErrorMessageDto](https://schema.vatis.tech/swagger-ui/index.html#/) Whether an error occurs or not, the connection will be closed with a `1000 - Normal Closure` code ### Diagrams ```mermaid sequenceDiagram participant C as Client participant S as Server C-->S: initial messages break on invalid client-sent messages S->>C: Error message end S-->>C: Normal connection close ``` ## API reference Please check the [WS Gateway API Reference](/api-reference/introduction.mdx) for API details. # Getting started Source: https://docs.vatis.tech/introduction Here you will find everything you need to know to get started with Vatis Streams. Welcome to Vatis Docs! Boost your application with our powerful Speech-to-Text and Audio Intelligence streaming APIs. Create an account and get your API key to start using Vatis Streams. Start transcribing audio files to text with our Speech-to-Text API. Process your live data feeds in real-time. Apply audio intelligence operations like summary, sentiment analysis, or your custom prompts over your audio content. Explore our integration samples repository. # Multilingual Code Switch Source: https://docs.vatis.tech/speech-to-text/multilingual-code-switch Auto-detect and switch between spoken language in your audio content The Multilingual Code Switch enables the processing of audio content that contains multiple languages by continuously detecting the spoken language and switching between the corresponding language models. ## Configuration This feature is implicitly enabled by not specifying the `language` parameter. To disable this feature, set the `language` parameter to a specific language (e.g. `language=en`). ## Results Each word in the [transcription-response](/api-reference/schemas/egress/transcription-response) will have a `language` field that indicates the detected language of the word. ```json { "transcription": " Good afternoon. Bună seara.", "words": [ { "word": " Good", "start": 1199, "end": 1520, "confidence": 1.0, "language": "en", "metadata": {} }, { "word": " afternoon.", "start": 1520, "end": 2020, "confidence": 0.99853516, "language": "en", "metadata": {} }, { "word": " Bună", "start": 2159, "end": 2320, "confidence": 1.0, "language": "ro", "metadata": {} }, { "word": " seara.", "start": 2320, "end": 2480, "confidence": 1.0, "language": "ro", "metadata": {} } ], "start": 0, "end": 3071, "metadata": {}, "utterance": false } ``` # Features Source: https://docs.vatis.tech/speech-to-text/pre-recorded/features Overview of the Pre-recorded API features. ## Model & Languages Automatically detect and switch between languages. More details [here](/speech-to-text/multilingual-code-switch). Detect speaker turns and cluster similar speaker turns together. ## Audio Format Send the files encoded in any format (`mp3`, `mp4`, `wav`, etc.) and we will transcode them automatically so that they can be processed. Support multiple channels files by processing each channel individually on the same stream. ## Sentiment Analysis Provide a summary of the processed content. [Details here](/audio-intelligence/summarization). Analyse the sentiment of the input content. [Details here](/audio-intelligence/sentiment-analysis). Create custom prompts to be applied on the processed content. [Details here](/audio-intelligence/ask-anything). # Getting Started Source: https://docs.vatis.tech/speech-to-text/pre-recorded/getting-started Get started with the Vatis Streams API for pre-recorded content ## Examples Visit our [GitHub samples repository](https://github.com/Vatis-Tech/vatis-streams-samples) for the complete list of examples on how to use the Vatis Streams API. ## Prerequisites * [Vatis API key](/get-started/get-api-access) * Linux shell * [cURL](https://curl.se/) or [Postman](https://www.postman.com/) for making HTTP or WebSocket requests * [jq](https://jqlang.github.io/jq/) for parsing JSON responses * `uuidgen` for generating UUIDs * a testing audio/video file ## Workflow ```bash export API_KEY= export STREAM_ID=$(uuidgen) export FILE_PATH= ``` The stream configuration defines what processing will be made on the input data (transcoding, transcription, diarization, audio intelligence, etc.). Pick one of the the predefined configurations: * [Pre-recorded transcription](/speech-to-text/pre-recorded/pre-recorded-transcription) * [Pre-recorded transcription w/ diarization](/speech-to-text/pre-recorded/speaker-diarization) Export the configuration ID: ```bash export CONFIG_ID= ``` Keep the stream configuration page opened in a separate tab for further references during this process Use one of the available gateways for uploading the data. Set the `streamConfigurationTemplateId=$CONFIG_ID`, `persist=true`, and any other patches as query parameters and upload the binary data as the body of the request. The configuration-specific patches (parameters) can be found under the `Parameters` section of the configuration page. When dealing with long parameter values (e.g. prompts) consider using the `HTTP Gateway with form-data` approach The body will be sent as binary data on the request body. The actual body can be one of the options mentioned under the `Input data` section of the configuration page. ```bash curl --request POST \ --url "https://http-gateway.vatis.tech/http-gateway/api/v1/upload?id=$STREAM_ID&streamConfigurationTemplateId=$CONFIG_ID&persist=true&language=en" \ --header "Authorization: Basic $API_KEY" \ --header 'Content-Type: application/octet-stream' \ --data-binary @"$FILE_PATH" | jq ``` To prevent any unexpected error, always include the `Content-Type: application/octet-stream` header [Endpoint reference](/api-reference/gateway/upload) We can use [dynamic webhooks](integration/webhooks#dynamic-webhooks) to specify callback URLs at the request level that will be triggered when the state changes for the stream resource we're creating. Generally, we'd want to know when the stream enters its `COMPLETED` or `FAILED` state. To declare a webhook for this two events we should set the following query parameters: * `webhook.stream.completed=http://my_domain/webhook-callback` * `webhook.stream.failed=http://my_domain/webhook-callback` The URL value of the `completed` and `failed` webhooks can be the same, and the actual state can be parsed from the received body The webhook URLs may need to be URL encoded depending on the requests library used We should also set the common `streamConfigurationTemplateId=$CONFIG_ID`, `persist=true`, and any other patches as query parameters and upload the binary data as the body of the request. ```bash curl --request POST \ --url "https://http-gateway.vatis.tech/http-gateway/api/v1/upload?id=$STREAM_ID&streamConfigurationTemplateId=$CONFIG_ID&persist=true&language=en&webhook.stream.completed=http://my_domain/webhook-callback&webhook.stream.failed=http://my_domain/webhook-callback" \ --header "Authorization: Basic $API_KEY" \ --header 'Content-Type: application/octet-stream' \ --data-binary @"$FILE_PATH" | jq ``` [Endpoint reference](/api-reference/gateway/upload) In some scenarios, the patches (parameters) values are too long to be included in the URL. In this case, we can use the `multipart/form-data` content type to send the patches as form data. The request body will contain exactly two parts in this specific order: 1. The patches as JSON encoded [HTTPStreamConfigurationDto](/api-reference/schemas/http-gateway/stream-configuration) 2. The binary data to be uploaded on the stream Here's an example of a stream configuration ```json { "patches": { "languages": "ro" ① }, "webhook": { "http://my_domain/path": [ ② "stream.completed", "stream.failed" ③ ] } } ``` ① The configuration-specific patches (parameters) can be found under the `Parameters` section of the configuration page ② The webhook URL ③ The events that will trigger the webhook. The complete list can be found [here](/integration/webhooks#event-types) The complete request will look like this: ```bash curl --request POST \ --url "https://http-gateway.vatis.tech/http-gateway/api/v1/upload?id=$STREAM_ID&streamConfigurationTemplateId=$CONFIG_ID&persist=true" \ --header "Authorization: Basic $API_KEY" \ --header 'Content-Type: multipart/form-data' \ --form 'config={ "patches": {"language": "en"} };type=application/json' \ --form "file=@$FILE_PATH;type=application/octet-stream" | jq ``` Considerations: * The first part has a limit of `1 MB` * If possible, include the part content type (`application/json`, and `application/octet-stream` respectively) * The parts name is not relevant [Endpoint reference](/api-reference/gateway/upload) Run the following command until the result is `COMPLETED`: ```bash curl --request GET \ --url "https://stream-service.vatis.tech/stream-service/api/v1/streams/$STREAM_ID" \ --header "Authorization: Basic $API_KEY" | jq '.state' ``` [Endpoint reference](/api-reference/streams/stream-resource-impl/find-by-id) The configured webhook will be triggered with a `POST` request having the [Webhook event](/api-reference/schemas/webhook/webhook-event) payload containing the [Stream state changed event](/api-reference/schemas/webhook/event-payload/stream-state-event). From the received payload we should extract the `streamId` and the [state](/api-reference/schemas/stream/stream-state) as shown below: ```json { //... "payload": { "streamId": "stream_id", "state": "COMPLETED" //... } } ``` If the stream state is `FAILED`, we should inspect the [stream errors](/infrastructure/streams/inspect-errors) and retry the upload. Refer to the [Webhook integration](/integration/webhooks) for the complete webhooks documentation. After the stream is completed, we can export the final result as JSON using the following command: ```bash curl --request GET \ --url "https://export-service.vatis.tech/export-service/api/v1/export/JSON?streams=$STREAM_ID" \ --header "Authorization: Basic $API_KEY" | jq ``` Based on the stream configuration, the result will be the one mentioned under the `Export response` section of the configuration. [Endpoint reference](/api-reference/export/exports-a-stream-of-data-in-various-formats) # Pre-recorded Transcription Source: https://docs.vatis.tech/speech-to-text/pre-recorded/pre-recorded-transcription Pre-recorded transcription specifications using the Vatis Streams API ### Stream configuration template ids * production all languages: `668115d123bca7e3509723d4` * [production Romanian-only](/speech-to-text/pre-recorded/romanian-pre-recorded-transcription) ### Input data * multimedia content: `wav`, `mp3`, `mp4`, `webm`, `flv`, etc. * public `http` or `https` link to multimedia file encoded in `UTF-8` ### Egress responses * [Egress Response](/api-reference/schemas/egress/stream-sink-message) * [Transcription Response](/api-reference/schemas/egress/transcription-response) * [LLM Response](/api-reference/schemas/egress/llm-response) ### Export response * [Audio Intelligence Response](/api-reference/schemas/export/audio-intelligence-response) ### Parameters The language as country [ISO code](/speech-to-text/pre-recorded/transcription-languages) to transcribe the audio to. When not specified, it is automatically detected. When multiple languages are specified, the model will auto-detect one of the specified languages. If multiple languages are specified, the language will perform multilingual code switching between the specified languages. If none is specified, the model will switch between all supported languages. To provide multiple languages in the URL, simply add multiple `language` parameters. For example: `language=en&language=es`. The threshold value to consider a segment as a speech segment. The value ranges from 0 to 1. Enable or disable voice activity detection. Possible values: `true` or `false`. Enable or disable splitting stereo audio into two mono audio streams. Possible values: `true` or `false`. Create a summary based on the upstream content. Summary length. Options are: `brief` or `detailed`. Summary tone. Options are: `conversational` or `informative`. Summary structure. Options are: `paragraphs` or `bullet_points`. Perform sentiment analysis on the upstream content. Specifies the custom prompt content for one of the `ask0`, `ask1`, ..., `askN` ask anything slots. When the content is specified, the prompt is considered activated. Otherwise, it is deactivated. Specifies the custom system prompt for one of the `ask0System`, `ask1System`, ..., `askNSystem` ask anything slots. Specifies the prompt id for one of the `ask0Id`, `ask1Id`, ..., `askNId` ask anything slots. The role of the prompt id is to identify the prompt in the responses. When unspecified, it will fallback on the index of the slot (e.g. `"0"`, `"1"`). Specifies the prompt response [JSON Schema](https://json-schema.org/overview/what-is-jsonschema) encoded as a string for one of the `ask0Format`, `ask1Format`, ..., `askNFormat` ask anything slots. When unspecified, the response not be structured in any particular way. When specified, the response will be a JSON object encoded as a string. Enable transcription enhancement. Balance the speed-accuracy ration of the transcription enhancing model. Provide a list of words to enhance the transcription. Those can be domain-specific terms that the model should pay special attention to. Provide a system prompt to guide the transcription enhancement model. This can help the model understand the context or specific requirements for the transcription. # Speaker Diarization Source: https://docs.vatis.tech/speech-to-text/pre-recorded/speaker-diarization Pre-recorded transcription with speaker diarization specifications using the Vatis Streams API ### Stream configuration template ids * production all languages: `669fee048452492b62cfad39` * [production Romanian-only](/speech-to-text/pre-recorded/romanian-speaker-diarization) ### Input data * multimedia content: `wav`, `mp3`, `mp4`, `webm`, `flv`, etc. * public `http` or `https` link to multimedia file encoded in `UTF-8` ### Egress responses * [Egress Response](/api-reference/schemas/egress/stream-sink-message) * [Transcription Response](/api-reference/schemas/egress/transcription-response) * [Diarization Response](/api-reference/schemas/egress/diarization-response) * [LLM Response](/api-reference/schemas/egress/llm-response) ### Export response * [Audio Intelligence Response](/api-reference/schemas/export/audio-intelligence-response) ### Parameters The language as country [ISO code](/speech-to-text/pre-recorded/transcription-languages) to transcribe the audio to. When not specified, it is automatically detected. When multiple languages are specified, the model will auto-detect one of the specified languages. If multiple languages are specified, the language will perform multilingual code switching between the specified languages. If none is specified, the model will switch between all supported languages. To provide multiple languages in the URL, simply add multiple `language` parameters. For example: `language=en&language=es`. The threshold value to consider a segment as a speech segment. The value ranges from 0 to 1. Enable or disable voice activity detection. Possible values: `true` or `false`. Enable or disable splitting stereo audio into two mono audio streams. Possible values: `true` or `false`. The `splitStereo` parameter should not be used in this configuration The number of speakers to diarize the audio to. When not specified, it is automatically detected. The minimum number of speakers to diarize the audio to. The maximum number of speakers to diarize the audio to. The audio intelligence layer operates only over the transcription responses, excluding the diarization information. Create a summary based on the upstream content. Summary length. Options are: `brief` or `detailed`. Summary tone. Options are: `conversational` or `informative`. Summary structure. Options are: `paragraphs` or `bullet_points`. Perform sentiment analysis on the upstream content. Specifies the custom prompt content for one of the `ask0`, `ask1`, ..., `askN` ask anything slots. When the content is specified, the prompt is considered activated. Otherwise, it is deactivated. Specifies the custom system prompt for one of the `ask0System`, `ask1System`, ..., `askNSystem` ask anything slots. Specifies the prompt id for one of the `ask0Id`, `ask1Id`, ..., `askNId` ask anything slots. The role of the prompt id is to identify the prompt in the responses. When unspecified, it will fallback on the index of the slot (e.g. `"0"`, `"1"`). Specifies the prompt response [JSON Schema](https://json-schema.org/overview/what-is-jsonschema) encoded as a string for one of the `ask0Format`, `ask1Format`, ..., `askNFormat` ask anything slots. When unspecified, the response not be structured in any particular way. When specified, the response will be a JSON object encoded as a string. Enable transcription enhancement. Balance the speed-accuracy ration of the transcription enhancing model. Provide a list of words to enhance the transcription. Those can be domain-specific terms that the model should pay special attention to. Provide a system prompt to guide the transcription enhancement model. This can help the model understand the context or specific requirements for the transcription. # Transcription languages Source: https://docs.vatis.tech/speech-to-text/pre-recorded/transcription-languages List of supported transcription languages | Language | ISO Code | | -------------- | -------- | | english | en | | chinese | zh | | german | de | | spanish | es | | russian | ru | | korean | ko | | french | fr | | japanese | ja | | portuguese | pt | | turkish | tr | | polish | pl | | catalan | ca | | dutch | nl | | arabic | ar | | swedish | sv | | italian | it | | indonesian | id | | hindi | hi | | finnish | fi | | vietnamese | vi | | hebrew | he | | ukrainian | uk | | greek | el | | malay | ms | | czech | cs | | romanian | ro | | danish | da | | hungarian | hu | | tamil | ta | | norwegian | no | | thai | th | | urdu | ur | | croatian | hr | | bulgarian | bg | | lithuanian | lt | | latin | la | | maori | mi | | malayalam | ml | | welsh | cy | | slovak | sk | | telugu | te | | persian | fa | | latvian | lv | | bengali | bn | | serbian | sr | | azerbaijani | az | | slovenian | sl | | kannada | kn | | estonian | et | | macedonian | mk | | breton | br | | basque | eu | | icelandic | is | | armenian | hy | | nepali | ne | | mongolian | mn | | bosnian | bs | | kazakh | kk | | albanian | sq | | swahili | sw | | galician | gl | | marathi | mr | | punjabi | pa | | sinhala | si | | khmer | km | | shona | sn | | yoruba | yo | | somali | so | | afrikaans | af | | occitan | oc | | georgian | ka | | belarusian | be | | tajik | tg | | sindhi | sd | | gujarati | gu | | amharic | am | | yiddish | yi | | lao | lo | | uzbek | uz | | faroese | fo | | haitian creole | ht | | pashto | ps | | turkmen | tk | | nynorsk | nn | | maltese | mt | | sanskrit | sa | | luxembourgish | lb | | myanmar | my | | tibetan | bo | | tagalog | tl | | malagasy | mg | | assamese | as | | tatar | tt | | hawaiian | haw | | lingala | ln | | hausa | ha | | bashkir | ba | | javanese | jw | | sundanese | su | # Features Source: https://docs.vatis.tech/speech-to-text/real-time/features Overview of the Real-time API features. ## Speech detection Detect the end of speech using the [Utterance End](/speech-to-text/utterance-end) feature. ## Audio Format Send the files encoded in any format (`mp3`, `mp4`, `wav`, etc.) and we will transcode them automatically so that they can be processed. Support multiple channels files by processing each channel individually on the same stream. ## Sentiment Analysis Provide a summary of the processed content. [Details here](/audio-intelligence/summarization). Analyse the sentiment of the input content. [Details here](/audio-intelligence/sentiment-analysis). Create custom prompts to be applied on the processed content. [Details here](/audio-intelligence/ask-anything). # Getting Started Source: https://docs.vatis.tech/speech-to-text/real-time/getting-started Start using the Vatis Streams API for real-time processing ## Examples Visit our [GitHub samples repository](https://github.com/Vatis-Tech/vatis-streams-samples) for more examples on how to use the Vatis Streams API. ## Prerequisites * [Vatis API key](/get-started/get-api-access) ## Create the WebSocket connection Connect to the Vatis Streams API using the WebSocket protocol. We can configure the stream by using either query parameters of a configuration message. Specify all the configuration parameters in the query string of the WebSocket URL. (e.g. `language`) ``` wss://ws-gateway.vatis.tech/ws-gateway/api/v1/?streamConfigurationTemplateId=670ba9e0efa59fe6aecd56f1&language=en ``` Connect to the WebSocket API specifying only the stream configuration template id in the URL. ``` wss://ws-gateway.vatis.tech/ws-gateway/api/v1/?streamConfigurationTemplateId=670ba9e0efa59fe6aecd56f1 ``` Send a [**configuration message**](/api-reference/schemas/websocket/configuration) to the WebSocket server after the connection is established. The configuration message is a JSON object with the configuration parameters. ```json { "type": "CONFIGURATION", "patches": { "language": "en" } } ``` ## Send your data Send your data to the WebSocket server as binary chunks from your data source. ```python with open('audio_file.wav', 'rb') as file: chunk = file.read(1024) while chunk: ws.send(chunk) chunk = file.read(1024) ``` ## Receive the results The first result message you'll receive is the [**stream metadata**](/api-reference/schemas/websocket/stream-metadata) message that will contain all the metadata of the created stream. The rest of the response stream will consist of either [**response messages**](/api-reference/schemas/websocket/stream-metadata) or binary message, if configured so. If an error is encountered during the processing, an [**error message**](/api-reference/schemas/websocket/error) will be sent, then the connection will be closed. ## Analyzing the result The response messages will contain a [**sink message**](/api-reference/schemas/egress/stream-sink-message) that wraps a processor message. The complete list of processor messages can be found in the [API reference](/api-reference/schemas/egress). Let's take for this example the [**transcription message**](/api-reference/schemas/egress/transcription-message) that contains the transcription of the audio data. ```json { "type": "RESPONSE", "response": { "streamId": "e9756f47-3222-4951-b372-15435b787c9f", "groupId": "e9756f47-3222-4951-b372-15435b787c9f", "tags": [ "main", "transcriber" ], "sinkTopicName": "e7de18ba", "messageId": "CKfpHhAnMAA", "processorId": "transcriber", "sequenceId": 39, "publishTimestamp": 1734449767699000, "frameType": "final", "payloadSchema": "tech.vatis.schema.stream.processor.messages.transcription.TranscriptionResponseDto", "payload": { "transcription": " George Washington.", "words": [ { "word": " George", "start": 30670, "end": 31150, "confidence": 0.99902344, "language": "en", "metadata": {} }, { "word": " Washington.", "start": 31150, "end": 31650, "confidence": 0.98706055, "language": "en", "metadata": {} } ], "start": 29150, "end": 32229, "metadata": {}, "utterance": false }, "headers": {} } } ``` The `RESPONSE` type of the message. The corresponding stream id that emitted this message. The type of the frame. Can be `final` or `partial`. A `final` frame represents the final processing result for a portion of the stream. The schema of the payload. The actual payload of type [TranscriptionResponseDto](/api-reference/schemas/egress/transcription-response). The transcription preview. ## Close the connection To confirm the input data was sent completely, send an [**end-of-stream message**](/api-reference/schemas/websocket/end-of-stream) to the WebSocket server. The engine will finish processing, send the final results, followed by a similar **end-of-stream** message, and then close the connection. ## Further reading Explore the complete [WS Gateway API reference](https://studio.asyncapi.com/?url=https://ws-gateway.vatis.tech/springwolf/docs\&readOnly) and the [WebSocket integration](/integration/websocket). # Real-time Transcription Source: https://docs.vatis.tech/speech-to-text/real-time/real-time-transcription Real-time transcription specifications using the Vatis Streams API ### Stream configuration template ids * production: `670ba9e0efa59fe6aecd56f1` ### Input data * multimedia content: `wav`, `mp3`, `mp4`, `webm`, `flv`, etc. ### Egress responses * [Egress Response](/api-reference/schemas/egress/stream-sink-message) * [Transcription Response](/api-reference/schemas/egress/transcription-response) * [LLM Response](/api-reference/schemas/egress/llm-response) ### Export response * [Audio Intelligence Response](/api-reference/schemas/export/audio-intelligence-response) ### Parameters The language as country [ISO code](/speech-to-text/real-time/transcription-languages) to transcribe the audio to. When not specified, it is automatically detected. Enable or disable multichannel audio processing. Possible values: `true` or `false`. When enabled, each channel is processed separately. The minimum waiting time in milliseconds after the last speech is detected before the emitting an `utterance` transcription message. Use these parameters only when sending raw data. The encoding of the audio data. Accepted values: * `linear16`: 16-bit signed little-endian samples (Linear PCM) * `flac`: Free Lossless Audio Codec * `mulaw`: 8-bit samples (G.711 mu-law) * `opus`: OGG Opus The sample rate of the audio data in Hertz (Hz). The number of audio channels in the audio data. Create a summary based on the upstream content. Summary length. Options are: `brief` or `detailed`. Summary tone. Options are: `conversational` or `informative`. Summary structure. Options are: `paragraphs` or `bullet_points`. Perform sentiment analysis on the upstream content. Specifies the custom prompt content for one of the `ask0`, `ask1`, ..., `askN` ask anything slots. When the content is specified, the prompt is considered activated. Otherwise, it is deactivated. Specifies the custom system prompt for one of the `ask0System`, `ask1System`, ..., `askNSystem` ask anything slots. Specifies the prompt id for one of the `ask0Id`, `ask1Id`, ..., `askNId` ask anything slots. The role of the prompt id is to identify the prompt in the responses. When unspecified, it will fallback on the index of the slot (e.g. `"0"`, `"1"`). Specifies the prompt response [JSON Schema](https://json-schema.org/overview/what-is-jsonschema) encoded as a string for one of the `ask0Format`, `ask1Format`, ..., `askNFormat` ask anything slots. When unspecified, the response not be structured in any particular way. When specified, the response will be a JSON object encoded as a string. Enable transcription enhancement. Balance the speed-accuracy ration of the transcription enhancing model. Provide a list of words to enhance the transcription. Those can be domain-specific terms that the model should pay special attention to. Provide a system prompt to guide the transcription enhancement model. This can help the model understand the context or specific requirements for the transcription. # Transcription languages Source: https://docs.vatis.tech/speech-to-text/real-time/transcription-languages List of supported transcription languages | Language | ISO Code | | ---------- | -------- | | english | en | | chinese | zh | | german | de | | spanish | es | | russian | ru | | french | fr | | japanese | ja | | portuguese | pt | | turkish | tr | | catalan | ca | | dutch | nl | | swedish | sv | | italian | it | | hindi | hi | | finnish | fi | | vietnamese | vi | | ukrainian | uk | | greek | el | | malay | ms | | czech | cs | | romanian | ro | | hungarian | hu | | norwegian | no | | thai | th | | bulgarian | bg | | lithuanian | lt | | slovak | sk | | latvian | lv | | estonian | et | # Utterance End Source: https://docs.vatis.tech/speech-to-text/utterance-end Use the utterance end flag to detect the end of speech The Utterance End feature can be used to detect the end of speech by waiting a configured amount of milliseconds of silence after the last detected speech. The end of speech is detected using a combination between the VAD (Voice Activity Detection) and the transcription model. The transcription model is also used to prevent false positives of speech detection by VAD. ## Configuration The Utterance End feature can be configured by using the `utteranceEnd=1000` query parameter, where `1000` is the amount of milliseconds of silence to wait after the last detected speech. ## Result When an utterance is ended, a [transcription response](/api-reference/schemas/egress/transcription-response) with the `"utterance": true` attribute is emitted. The content of the response can be a transcription response or an empty transcription, depending on the underlying engine implementation. ```json { "transcription": "", "words": [], "start": 6480, "end": 6480, "metadata": {}, "utterance": true } ```