The SESTEK Speech Recognition (SR) API offers two kinds of speech recognition services:
- Speech Dictation Service: make speech dictation with a language model (Method 1 below).
- Speech Recognition Service: make speech recognition with a grammar (Method 2 below).
Authentication
Cloud deployments require a bearer token, sent as the Authorization header, for both methods below. On-premises deployments don't use tokens at all, the host machine is licensed once via the License Service application instead, and neither method needs an Authorization header there. See Authentication for both flows.
Method 1: Dictation
Use dictation for free-form speech. Recognition runs on end-to-end (E2E) models: rather than a separate acoustic model and language model chained together, a single trained model maps audio directly to text.
You choose from the models already available on your tenant, see Language Models; this endpoint doesn't let you define new ones. If you need a model that isn't already available, contact your SESTEK Sales Operations contact.
Endpoint
POST {{ADDR_SERVICE}}/v1/speech/dictation/request
Replace {{ADDR_SERVICE}} with your deployment's base address: your region's URL on cloud (see API Region URLs), or your machine's address on-premises.
Request Headers
| Header | Required | Description |
|---|---|---|
ModelName |
Yes | The language model to use. See Language Models. |
Tenant |
No | Defaults to Default. |
ModelVersion |
No | Defaults to the latest available version if omitted or set to 0. |
ProduceNBestList |
No | If true, returns multiple recognition hypotheses instead of one. |
NBestListLength |
No | Maximum number of hypotheses returned when ProduceNBestList is true. |
SendAudioDownloadLink |
No | If true, the response includes a temporary download link for the submitted audio. |
Authorization |
Yes on cloud, not used on-premises | Bearer <access_token> on cloud; omit this header entirely on-premises. |
Content-Type |
Yes | audio/opus, audio/wav, audio/wave, ... |
Common audio formats beyond these three, such as mp3, are also generally supported; confirm the exact Content-Type value with SESTEK's Application Support team if you need one not listed here. If you have uncompressed audio and want to compress it before sending to reduce network usage, use opus: of the supported formats, it's the one that affects recognition accuracy the least.
Example Request
curl --location '{{ADDR_SERVICE}}/v1/speech/dictation/request' \
--header 'ModelName: English' \
--header 'Tenant: Default' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: audio/wave' \
--data-binary '@audio.wav'
On-premises, drop the Authorization header entirely, everything else stays the same.
This omits ModelVersion, so the latest available version of the English model is used automatically. Add ModelVersion only if you need to pin a specific one.
Example Response
{
"resultText": "hello everyone",
"confidence": 1,
"speechStartTimeMsec": 0,
"speechEndTimeMsec": 2437,
"nbestlist": {
"utterances": [
{
"nlsmlResult": "",
"confidence": 99,
"recognizedWords": [
{
"word": "hello",
"startTimeMsec": 410,
"endTimeMsec": 1110,
"confidence": 99,
"wordType": 1,
"speakerId": null
},
{
"word": "everyone",
"startTimeMsec": 1140,
"endTimeMsec": 1960,
"confidence": 99,
"wordType": 1,
"speakerId": null
}
]
}
]
},
"audioLink": "https://.../audio.wav",
"success": true,
"errorMessage": null,
"errorCode": null,
"moreInfo": null
}
Response Fields
| Field | Description |
|---|---|
resultText |
The dictated (recognized) text. |
confidence |
Confidence score of the recognition, range 0 to 1. |
speechStartTimeMsec / speechEndTimeMsec |
Where speech starts and ends in the audio, in milliseconds. |
nbestlist.utterances |
Present when ProduceNBestList is true; one entry per hypothesis. |
nbestlist.utterances[].recognizedWords |
Word-level detail: word, startTimeMsec, endTimeMsec, confidence, wordType (Normal, Filler, Suffix, or Prefix), speakerId. |
audioLink |
Present when SendAudioDownloadLink is true. |
success / errorMessage / errorCode / moreInfo |
Standard result and error fields. |
Method 2: Grammar-Based Recognition
Use grammar-based recognition instead of dictation when the expected responses are limited and known in advance, such as menu options, city names, or yes/no confirmations, a constrained set of words and phrases you define, rather than a general-purpose language model.
Grammar Formats
Two grammar formats are supported:
- SRGS XML (recommended): the W3C Speech Recognition Grammar Specification format, with SISR and NLSML support.
- List (SESTEK custom list): a plain list of words, one per line. Supported for Turkish only and kept for backward compatibility; use SRGS XML for new projects.
Example SRGS XML grammar
<?xml version="1.0" encoding="UTF-8" ?>
<grammar mode="voice" tag-format="semantics/1.0" xml:lang="en-US" version="1.0" root="main">
<rule id="main">
<one-of>
<item>Apple</item>
<item>Banana</item>
</one-of>
</rule>
</grammar>
Managing Grammars
These endpoints are grouped under the
{{ADDR_UTIL}}variable in the Postman collection. On cloud, they're reachable at{{ADDR_SERVICE}}instead, same as dictation and recognition, with a valid bearer token. On-premises, use whichever address your deployment's grammar service is actually configured at (typically{{ADDR_UTIL}}); check your local setup if unsure.
GET Grammars
GET {{ADDR_SERVICE}}/v1/speech/recognition/grammars
curl --location '{{ADDR_SERVICE}}/v1/speech/recognition/grammars' \
--header 'Authorization: Bearer <access_token>'
{
"grammars": [
{
"id": 125,
"name": "my42",
"tenant": "default",
"type": "application/srgs+xml"
}
],
"success": true,
"errorMessage": null,
"errorCode": null,
"moreInfo": null
}
On-premises, drop the Authorization header entirely, everything else stays the same.
| Field | Description |
|---|---|
grammars |
An array of objects describing each available grammar: id, name, tenant, type. |
success / errorMessage / errorCode / moreInfo |
Standard result and error fields. |
Error Response Example
{
"success": false,
"errorMessage": "Unexpected Error",
"errorCode": "internal-service-error",
"moreInfo": null
}
GET Specific Grammars
GET {{ADDR_SERVICE}}/v1/speech/recognition/grammars/{id} downloads the grammar's file content.
POST Grammars
POST {{ADDR_SERVICE}}/v1/speech/recognition/grammars
| Header | Required | Description |
|---|---|---|
GrammarName |
Yes | Name to save the grammar under. Uploading an existing name overwrites it. |
Tenant |
No | Defaults to Default. |
Content-Type |
Yes | application/srgs+xml or application/x-gslist |
Authorization |
Yes on cloud, not used on-premises | Bearer <access_token> on cloud; omit this header entirely on-premises. |
curl --header 'GrammarName: NewGrammar' \
--header 'Tenant: Default' \
--header 'Content-Type: application/srgs+xml' \
--header 'Authorization: Bearer <access_token>' \
--data-binary '@NewGrammar.grxml' \
-X POST '{{ADDR_SERVICE}}/v1/speech/recognition/grammars'
On-premises, drop the Authorization header entirely, everything else stays the same.
{ "success": true, "id": 126, "errorMessage": null, "errorCode": null, "moreInfo": null }
Error Response Example
{
"success": false,
"errorMessage": "Recognition-Parameters Are Not Defined At Header",
"errorCode": "missing-parameter",
"moreInfo": null
}
Grammar file names must be in ANSI format, since they are used as HTTP header values, and grammar file contents must be UTF-8 encoded.
If you're using the List format instead, set Content-Type to application/x-gslist and send one word or phrase per line:
curl --header 'GrammarName: NewListGrammar' \
--header 'Tenant: Default' \
--header 'Content-Type: application/x-gslist' \
--header 'Authorization: Bearer <access_token>' \
--data-binary 'Boston
Chicago
Denver
Seattle' \
-X POST '{{ADDR_SERVICE}}/v1/speech/recognition/grammars'
On-premises, drop the Authorization header entirely, everything else stays the same.
POST Generate Grammar
If you have a list of words rather than a hand-written SRGS file, this endpoint generates a valid SRGS XML grammar for you.
POST {{ADDR_SERVICE}}/v1/speech/recognition/grammars/generator
| Header | Required | Description |
|---|---|---|
Content-Type |
Yes | Must be text/plain. |
language |
No | Defaults to tr-TR. |
Authorization |
Yes on cloud, not used on-premises | Bearer <access_token> on cloud; omit this header entirely on-premises. |
The request body is the word list, one word per line.
curl -X POST '{{ADDR_SERVICE}}/v1/speech/recognition/grammars/generator' \
-H 'Content-Type: text/plain' \
-H 'language: en-US' \
-H 'Authorization: Bearer <access_token>' \
-d 'apple
banana'
On-premises, drop the Authorization header entirely, everything else stays the same.
Example Response
<?xml version="1.0" encoding="UTF-8" ?>
<grammar mode="voice" tag-format="semantics/1.0" xml:lang="en-US" version="1.0" root="main">
<rule id="main">
<one-of>
<item>apple<tag>out = "apple";</tag></item>
<item>banana<tag>out = "banana";</tag></item>
</one-of>
</rule>
</grammar>
Error Response Example
{
"errorCode": "cannot-generate-grammar",
"errorMessage": "failed to generate grammar",
"moreInfo": "Content-Type has not been specified",
"success": false
}
DELETE Grammars
DELETE {{ADDR_SERVICE}}/v1/speech/recognition/grammars/{id}
POST Recognition Request
POST {{ADDR_SERVICE}}/v1/speech/recognition/request
| Header | Required | Description |
|---|---|---|
GrammarName |
Yes | The grammar to recognize against. |
Frequency |
Yes | Send 8000 unless otherwise instructed. This does not need to match your audio file's actual sample rate, which is read from the file itself. |
Tenant |
No | Defaults to Default. |
SendAudioDownloadLink |
No | If true, the response includes a temporary download link for the submitted audio. |
Authorization |
Yes on cloud, not used on-premises | Bearer <access_token> on cloud; omit this header entirely on-premises. |
Content-Type |
Yes | audio/opus, audio/wav, or audio/wave |
Common audio formats beyond these three, such as mp3, are also generally supported; confirm the exact Content-Type value with SESTEK's Application Support team if you need one not listed here. If you have uncompressed audio and want to compress it before sending to reduce network usage, use opus: of the supported formats, it's the one that affects recognition accuracy the least.
curl --location '{{ADDR_SERVICE}}/v1/speech/recognition/request' \
--header 'Content-Type: audio/wave' \
--header 'GrammarName: SampleGrammar' \
--header 'Tenant: Default' \
--header 'Frequency: 8000' \
--header 'Authorization: Bearer <access_token>' \
--data-binary '@audio.wav'
On-premises, drop the Authorization header entirely, everything else stays the same.
{
"confidence": 0.99,
"recognizedText": "Apple",
"semanticResult": "Apple",
"speechStartTimeMsec": 0,
"speechEndTimeMsec": 1125,
"audioLink": "https://.../audio.wav",
"success": true,
"errorMessage": null,
"errorCode": null,
"moreInfo": null
}
Error Response Example
{
"success": false,
"errorMessage": "GrammarName has not been specified",
"errorCode": "missing-parameter",
"moreInfo": null
}
| Field | Description |
|---|---|
recognizedText |
Plain text recognition result. |
semanticResult |
A machine-processable representation of the result, which can carry more structure than the plain text. |
confidence |
Confidence score, range 0 to 1. |
speechStartTimeMsec / speechEndTimeMsec |
Where speech starts and ends in the audio, in milliseconds. |
audioLink |
Present when SendAudioDownloadLink is true. |
success / errorMessage / errorCode / moreInfo |
Standard result and error fields. |
POST Validation
Use this when you have a short audio clip and want to confirm whether it matches a specific expected phrase, without needing a grammar file; the service generates one for the check automatically.
POST {{ADDR_SERVICE}}/v1/speech/recognition/validation
Send as multipart/form-data with two parts:
validation-parameters (JSON):
| Field | Description |
|---|---|
validationText |
The text to check the audio against. |
language |
Language culture of the text, for example tr-TR or en-US. |
frequency |
Frequency of the audio file. Optional. |
sendDownloadLink |
If true, the response includes a link to download the submitted audio. Defaults to false. |
upload: the audio file to validate, in wav or opus format.
curl --form 'validation-parameters={"validationText":"Alaska","language":"en-US","sendDownloadLink":true};type=application/json' \
--form 'upload=@Alaska.wav;type=audio/wav' \
-X POST '{{ADDR_SERVICE}}/v1/speech/recognition/validation'
On cloud, add --header 'Authorization: Bearer <access_token>'; on-premises, no Authorization header is needed.
{
"answer": "valid",
"moreInfo": "RecognizedText : Alaska",
"audioLink": "Not Available"
}
| Field | Description |
|---|---|
answer |
valid if the audio matches validationText, notValid if it doesn't. |
moreInfo |
Additional detail about the result, such as the actual recognized text. |
audioLink |
Your submitted audio in wave format, present when sendDownloadLink is true; otherwise Not Available. |
