사이드 메뉴
커뮤니케이션
API 제공
어드민 API
REST API
이 문서는 음성 REST API 사용 방법을 안내합니다.
| 페이즈 | 호스트 |
|---|---|
| 알파(Alpha) | https://alpha-newtone-api.i.kakao.com |
| 샌드박스(Sandbox) | https://sbx-newtone-api.i.kakao.com |
| 프로덕션(Production) | https://prod-newtone-api.i.kakao.com |
음성 인식은 웹 소켓 또는 파일 업로드 방식으로 사용할 수 있습니다. 아래 내용을 참고해 서비스에 보다 적합한 구현 방식을 선택합니다.
| 구현 방식 | 설명 |
|---|---|
| 웹 소켓 | 실시간 스트리밍 방식, 웹 소켓 방식 동작 과정 참고 음성 서버가 최종 결과를 반환하거나, 클라이언트에서 인식 종료를 요청하기 전까지 지속적으로 음성 인식 가능 상태 유지 실시간으로 발화 내용을 입력받아 음성 인식을 요청하는 경우에 사용 |
| 파일 업로드 | 동기 또는 비동기 방식, 파일 업로드 방식 동작 과정 참고 발화 내용을 먼저 녹음해 음성 파일로 만든 후 음성 인식을 요청하는 경우에 사용 동기 방식: 파일 업로드로 음성 인식을 요청한 후 결과를 응답받기까지 네트워크 연결 유지 비동기 방식: 파일 업로드로 음성 인식을 요청하고, 파일 업로드 및 인식 종료 후 결과 파일 다운로드 |
- 서비스 클라이언트가 단문 인식: 웹 소켓 또는 장문 인식: 웹 소켓 URL로 음성 인식 시작(
recogStart)을 요청합니다. - 음성 API 서버가 음성 인식 준비 완료(
ready) 확인 메시지를 전달합니다. - 서비스 클라이언트가 음성 데이터를 전달합니다.
- 음성 API 서버가 음성 데이터 인식 시작(
beginPointDetection) 메시지를 전달한 후, 음성 인식 중간 결과(partialResult) 메시지를 전달합니다. - 음성 API 서버가 음성 데이터 전달 종료 판단(
endPointDetection) 시 최종 결과(finalResult) 메시지를 전달합니다. - 음성 API 서버가 음성 인식을 종료 처리합니다.
- 서비스 클라이언트가 장문 인식: 웹 소켓 URL로 음성 인식 시작(
recogStart)을 요청합니다. - 음성 API 서버가 음성 인식 준비 완료(
ready) 확인 메시지를 전달한 후, 단문 인식의 3~5 과정을 반복합니다. 장문 인식 중에는 최종 결과가 여러 번 반환될 수 있습니다. - 서비스 클라이언트가 음석 인식 종료(
recogEnd) 메시지를 발송합니다. - 음성 API 서버가 음성 인식을 종료 처리합니다. 장시간 음성 데이터 전달이 없는 경우에도 음성 인식 종료 처리합니다.
- 서비스 클라이언트가 동기 인식: 파일 업로드를 요청합니다. 응답을 받기까지 네트워크 연결이 유지됩니다.
- 음성 API 서버가 음성 파일을 인식한 후 결과를 반환합니다. 결과 반환 시 네트워크 연결이 종료됩니다.
- 서비스 클라이언트가 비동기 인식: 파일 업로드를 요청합니다.
- 음성 API 서버가 요청 결과 코드와 결과 파일 URL을 반환합니다. 결과 파일 다운로드는 파일 업로드 상태가 인식 종료(
FINISH)로 변경된 후 가능합니다. - 서비스 클라이언트가 음성 파일 업로드 상태 조회를 요청합니다.
- 음성 API 서버가 파일 업로드 상태를 반환합니다.
- 서비스 클라이언트가 비동기 인식: 파일 업로드 응답으로 받은 결과 파일 URL(
result)로 결과 파일을 다운로드해 확인합니다. - 카카오 내부 저장소(
tenth2)에 저장된 결과 파일이 제공됩니다.
음성 인식은 음성 인식 결과를 부분 결과와 최종 결과로 나누어 전달합니다.
| 결과 유형 | 설명 |
|---|---|
| 중간 결과 ( partialResult) | 음성 인식 시작부터 중단 시점까지의 음성 인식 결과 이어 말하기와 같이 추가적으로 전달된 음성 데이터의 인식 결과가 다음 중간 결과에 반영됨 음성 인식이 단문 단위로 완성된 후에는 중간 결과가 아닌 최종 결과를 제공함 예시 음성 데이터 "안녕하세요" 전달 시 중간 결과는 "안녕하세요" 문자열 이어서 음성 데이터 "카카오"를 추가 전달 시 중간 결과는 "안녕하세요 카카오" 문자열 |
| 최종 결과 ( finalResult) | 음성 인식 시작부터 종료까지의 음성 인식 결과 예시 음성 데이터 "안녕하세요 카카오입니다" 전달 시 최종 결과는 "안녕하세요 카카오입니다" 문자열 |
실시간 스트리밍 방식인 단문 인식: 웹 소켓, 장문 인식: 웹 소켓은 단문 단위의 최종 결과를 반환합니다. 단문 단위 이하의 입력 중인 음성 데이터는 중간 결과를 반환합니다.
동기 인식: 파일 업로드, 비동기 인식: 파일 업로드는 항상 최종 결과를 반환합니다.
짧은 발화 내용을 인식해 문자로 변환합니다. 실시간 스트리밍 방식으로, 여러 차례 단문 인식을 요청할 수 있습니다. 요구사양에서 지원하는 데이터 포맷을 확인하고 사용해야 합니다.
헤더에 REST API 키를 담아 GET으로 요청합니다. 음성 인식 요청에 대한 정보를 본문에 JSON 형식으로 전달해야 합니다.
요청 성공 시 음성 API 서버와의 네트워크 연결이 시작되고 음성 데이터를 바이너리(Binary) 형식으로 전송할 수 있습니다. 단문 인식이 완료되면 음성 API 서버로부터 최종 결과가 전달되고 음성 인식 종료 처리됩니다. 웹 소켓 방식 동작 과정을 참고합니다.
| 이름 | 설명 | 필수 |
|---|---|---|
| Authorization | Authorization: KakaoAK ${REST_API_KEY}인증 방식, REST API 키로 인증 요청 | O |
| Content-Type | Content-Type: application/json요청 데이터 타입 | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| type | String | 서비스 클라이언트에서 보내는 요청 타입 메시지, 아래 중 하나
| O |
| service | String | 아래로 고정DICTATION: 받아쓰기 서비스 모드 | O |
| language | String | 음성 데이터 언어, 아래 중 하나
중요: ko_KR 이외의 언어는 Voice Interface 아지트에서 별도 협의 후 사용 가능 | O |
| showFinalOnly | Boolean | 최종 결과만 응답받도록 설정
false) | X |
| showExtraInfo | Boolean | 요청 타임스탬프(Timestamp) 등 추가 정보를 제공받도록 설정
false) | X |
| audioFormat | String | 음성 데이터 포멧${CODEC}/${BIT_DEPTH}/${SAMPLE_RATE}/${CHANNEL}/_/_ 형식, 아래 중 하나
| O |
| requestId | String | 요청 식별용 ID | X |
| passinfo | String | 요청에 포함할 기타 정보 데이터zlib 압축 또는 Base64 인코딩 없이 원본 객체 그대로 전달 | X |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| type | String | 음성 API 서버에서 보내는 요청 처리 상태 타입 메시지, 아래 중 하나
| O |
| value | String | 요청 처리 상태 타입에 대한 상세 정보 또는 음성 인식 결과 문자열 에러가 발생한 경우에는 에러 메시지 | O |
| resultInfo | String | 단어의 인식 시작과 끝 시간 정보, type이 finalResult인 경우에만 응답에 포함 | X |
| nBest | NBest | 최종 인식 결과 정보(최대 10개), type이 finalResult인 경우에만 응답에 포함 | X |
| durationMS | Int | 최종 결과 응답 시까지 전달된 음성의 총 길이(단위: ms)type이 finalResult인 경우에만 응답에 포함 | X |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| value | String | 인식 결과 텍스트 | O |
| resultInfo | String | 단어의 인식 시작과 끝 시간 정보 | O |
| score | Int | 인식 결과의 신뢰도 점수 | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| value | String | 에러 메시지 | O |
요청
package mainimport ("bufio""encoding/json""errors""io""log""net/url""os""time""github.com/gorilla/websocket""github.com/labstack/gommon/random")type RecogStart struct {Type string `json:"type"`Service string `json:"service"`ShowFinalOnly bool `json:"showFinalOnly"`ShowExtraInfo bool `json:"showExtraInfo"`RecogLongMaxWaitTime int `json:"recogLongMaxWaitTime"`AudioFormat string `json:"audioFormat"`RequestId string `json:"requestId"`PassInfo PassInfoPayload `json:"passinfo"`}type AIaaSInfo struct {UserID string `json:"userId,omitempty"`Domain string `json:"domain,omitempty"`Phase string `json:"phase,omitempty"`ShowFinalOnly bool `json:"showFinalOnly,omitempty"`ShowExtraInfo bool `json:"showExtraInfo,omitempty"`}type GivenEPD struct {Active bool `json:"active,omitempty"`Start int `json:"start,omitempty"`End int `json:"end,omitempty"`}type PassInfoPayload struct {AIaaSInfo `json:"aiaasInfo,omitempty"`GivenEPD `json:"givenepd,omitempty"`RequestID string `json:"requestId,omitempty"`KAccountID int `json:"kaccountid,omitempty"`AIID string `json:"aiid,omitempty"`UserAgent interface{} `json:"userAgent,omitempty"`ServiceID string `json:"serviceId,omitempty"`ServiceName string `json:"serviceName,omitempty"`Format string `json:"format,omitempty"`Activator interface{} `json:"activator,omitempty"`VoiceProfile interface{} `json:"voiceProfile,omitempty"`Domains interface{} `json:"domains,omitempty"`Entities interface{} `json:"entities,omitempty"`PreserveVoiceData bool `json:"preserveVoiceData,omitempty"`EnableSpeakerDiarization bool `json:"enableSpeakerDiarization,omitempty"`DialogRequestId string `json:"dialogRequestId,omitempty"`DialogRequestOffset int `json:"dialogRequestOffset,omitempty"`RecogLongMaxWaitTime int `json:"recogLongMaxWaitTime,omitempty"`EPDTimeOutMS int `json:"epdTimeOutMS,omitempty"`EPDHangOverMS int `json:"epdHangOverMS,omitempty"`SpeakerDiarizationSize int `json:"speakerDiarizationSize,omitempty"`TTSConfig interface{} `json:"ttsConfig,omitempty"`TTSSource interface{} `json:"ttsSource,omitempty"`}const (DefaultPreserveVoiceData = trueDefaultRecogLongMaxWaitTime = 60000DefaultRecogFormat = "RAWPCM/16/16000/1/_/_"//DefaultRecogFormat = "RAWPCM/16/8000/1/_/_")func NewPassInfoPayload() PassInfoPayload {return PassInfoPayload{AIaaSInfo: AIaaSInfo{},Format: DefaultRecogFormat,RecogLongMaxWaitTime: DefaultRecogLongMaxWaitTime,PreserveVoiceData: DefaultPreserveVoiceData,RequestID: "",}}type RecogEnd struct {Type string `json:"type"`}type ResponseMessage struct {Type string `json:"type"`Value string `json:"value"`}func main() {log.SetFlags(log.Lmicroseconds)idxstr := random.String(15)requestId := "GNT-" + idxstr// must modify endpointendPointURI := "wss://prod-newtone-api.i.kakao.com/v2/ai/newtone-recognize/ws"endPoint, err := url.Parse(endPointURI)if err != nil {log.Fatalf("[%s] url parse err: %s", requestId, err.Error())}// must modify file pathfilePath := "./heykakao_hello.wav" //"{File Path}"f, err := os.Open(filePath)if err != nil {log.Fatalf("[%s] file open err: %s", requestId, err.Error())}defer f.Close()recognize(endPoint, f, requestId)}func recognize(u *url.URL, r io.Reader, requestId string) {log.Printf("[%s] connecting to %s", requestId, u.String())headers := http.Header{}headers.Set("Authorization", "KakaoAK ${REST_API_KEY}")c, _, err := websocket.DefaultDialer.Dial(u.String(), headers)if err != nil {log.Fatalf("[%s] dial: %s", requestId, err.Error())}defer c.Close()passinfo1 := NewPassInfoPayload()// 1. send recogStart messagestartMsg := RecogStart{Type: "recogStart",Service: "DICTATION",ShowFinalOnly: false,ShowExtraInfo: false,RecogLongMaxWaitTime: 3600000,AudioFormat: "RAWPCM/16/16000/1/_/_",//AudioFormat: "RAWPCM/16/8000/1/_/_",RequestId: requestId,PassInfo: passinfo1,//PassInfo: string(passinfo),}if err := c.WriteJSON(startMsg); err != nil {log.Printf("[%s] start err: %s", requestId, err.Error())return}log.Printf("[%s] send: %+v", requestId, startMsg)// 2. async read server messageticker := time.NewTicker(65 * time.Minute)defer ticker.Stop()exit := make(chan bool, 1)go func() {defer func() {exit <- true}()for {select {case <-ticker.C:log.Printf("[%s] exit by ticker", requestId)returndefault:_, message, err := c.ReadMessage()if err != nil {log.Printf("[%s] ReadMessage: %s", requestId, err.Error())return}log.Printf("[%s] recv: %s", requestId, message)var respMsg ResponseMessagejson.Unmarshal(message, &respMsg)if respMsg.Type == "ELR" {return}}}}()// 3. send audio binary message (file)br := bufio.NewReader(r)data := make([]byte, 640)cumulativeReadSize := 0readStartTime := time.Now()for {rbytes, err := br.Read(data)if err != nil {if errors.Is(err, io.EOF) {log.Printf("[%s] EOF", requestId)break} else {log.Printf("[%s] read err: %s", requestId, err.Error())return}}cumulativeReadSize += rbyteslog.Printf("[%s] cumulative read size: %d", requestId, cumulativeReadSize)if err := c.WriteMessage(websocket.BinaryMessage, data[:rbytes]); err != nil {log.Printf("[%s] write: %s", requestId, err.Error())return}// control sending speed (640Bytes / 20ms)for cumulativeReadSize > 32*int(time.Now().Sub(readStartTime).Milliseconds()) {time.Sleep(20 * time.Millisecond)}}// 4. send recogEnd messageendMsg := RecogEnd{Type: "recogEnd"}if err := c.WriteJSON(endMsg); err != nil {log.Printf("[%s] end err: %s", requestId, err.Error())return}log.Printf("[%s] send: %+v", requestId, endMsg)<-exit}
응답
- 음성 API 서버가 전달하는 메시지 예제입니다.
{"type": "ready","sessionId": "${SESSION_ID}"}
긴 발화 내용을 인식해 문자로 변환합니다. 실시간 스트리밍 방식으로, 대화와 같이 여러 차례 중단점이 있는 장문 인식을 지속적으로 요청할 수 있습니다. 요구사양에서 지원하는 데이터 포맷을 확인하고 사용해야 합니다.
헤더에 REST API 키를 담아 GET으로 요청합니다. 음성 인식 요청에 대한 정보를 본문에 JSON 형식으로 전달해야 합니다.
요청 성공 시 음성 API 서버와의 네트워크 연결이 시작되고 음성 데이터를 바이너리(Binary) 형식으로 전송할 수 있습니다. 음성 API 서버는 전달된 음성 데이터에 대해 중간 결과와 최종 결과를 여러 차례 반환할 수 있습니다. 서비스 클라이언트가 음성 인식 종료 요청 메시지를 보내거나, 장시간 음성 데이터가 전달되지 않으면 음성 인식 종료 처리됩니다. 웹 소켓 방식 동작 과정을 참고합니다.
- 단문 인식: 웹 소켓 참고
- 단문 인식: 웹 소켓 참고
요청
package mainimport ("bufio""encoding/json""errors""io""log""net/url""os""time""github.com/gorilla/websocket""github.com/labstack/gommon/random")type RecogStart struct {Type string `json:"type"`Service string `json:"service"`ShowFinalOnly bool `json:"showFinalOnly"`ShowExtraInfo bool `json:"showExtraInfo"`RecogLongMaxWaitTime int `json:"recogLongMaxWaitTime"`AudioFormat string `json:"audioFormat"`RequestId string `json:"requestId"`PassInfo PassInfoPayload `json:"passinfo"`}type AIaaSInfo struct {UserID string `json:"userId,omitempty"`Domain string `json:"domain,omitempty"`Phase string `json:"phase,omitempty"`ShowFinalOnly bool `json:"showFinalOnly,omitempty"`ShowExtraInfo bool `json:"showExtraInfo,omitempty"`}type GivenEPD struct {Active bool `json:"active,omitempty"`Start int `json:"start,omitempty"`End int `json:"end,omitempty"`}type PassInfoPayload struct {AIaaSInfo `json:"aiaasInfo,omitempty"`GivenEPD `json:"givenepd,omitempty"`RequestID string `json:"requestId,omitempty"`KAccountID int `json:"kaccountid,omitempty"`AIID string `json:"aiid,omitempty"`UserAgent interface{} `json:"userAgent,omitempty"`ServiceID string `json:"serviceId,omitempty"`ServiceName string `json:"serviceName,omitempty"`Format string `json:"format,omitempty"`Activator interface{} `json:"activator,omitempty"`VoiceProfile interface{} `json:"voiceProfile,omitempty"`Domains interface{} `json:"domains,omitempty"`Entities interface{} `json:"entities,omitempty"`PreserveVoiceData bool `json:"preserveVoiceData,omitempty"`EnableSpeakerDiarization bool `json:"enableSpeakerDiarization,omitempty"`DialogRequestId string `json:"dialogRequestId,omitempty"`DialogRequestOffset int `json:"dialogRequestOffset,omitempty"`RecogLongMaxWaitTime int `json:"recogLongMaxWaitTime,omitempty"`EPDTimeOutMS int `json:"epdTimeOutMS,omitempty"`EPDHangOverMS int `json:"epdHangOverMS,omitempty"`SpeakerDiarizationSize int `json:"speakerDiarizationSize,omitempty"`TTSConfig interface{} `json:"ttsConfig,omitempty"`TTSSource interface{} `json:"ttsSource,omitempty"`}const (DefaultPreserveVoiceData = trueDefaultRecogLongMaxWaitTime = 60000DefaultRecogFormat = "RAWPCM/16/16000/1/_/_"//DefaultRecogFormat = "RAWPCM/16/8000/1/_/_")func NewPassInfoPayload() PassInfoPayload {return PassInfoPayload{AIaaSInfo: AIaaSInfo{},Format: DefaultRecogFormat,RecogLongMaxWaitTime: DefaultRecogLongMaxWaitTime,PreserveVoiceData: DefaultPreserveVoiceData,RequestID: "",}}type RecogEnd struct {Type string `json:"type"`}type ResponseMessage struct {Type string `json:"type"`Value string `json:"value"`}func main() {log.SetFlags(log.Lmicroseconds)idxstr := random.String(15)requestId := "GNT-" + idxstr// must modify endpointendPointURI := "wss://prod-newtone-api.i.kakao.com/v2/ai/newtone-recognize/long/ws"endPoint, err := url.Parse(endPointURI)if err != nil {log.Fatalf("[%s] url parse err: %s", requestId, err.Error())}// must modify file pathfilePath := "./long_sample.wav" //"{File Path}"f, err := os.Open(filePath)if err != nil {log.Fatalf("[%s] file open err: %s", requestId, err.Error())}defer f.Close()recognize(endPoint, f, requestId)}func recognize(u *url.URL, r io.Reader, requestId string) {log.Printf("[%s] connecting to %s", requestId, u.String())headers := http.Header{}headers.Set("Authorization", "KakaoAK ${REST_API_KEY}")c, _, err := websocket.DefaultDialer.Dial(u.String(), headers)if err != nil {log.Fatalf("[%s] dial: %s", requestId, err.Error())}defer c.Close()passinfo1 := NewPassInfoPayload()// 1. send recogStart messagestartMsg := RecogStart{Type: "recogStart",Service: "DICTATION",ShowFinalOnly: false,ShowExtraInfo: false,RecogLongMaxWaitTime: 3600000,AudioFormat: "RAWPCM/16/16000/1/_/_",//AudioFormat: "RAWPCM/16/8000/1/_/_",RequestId: requestId,PassInfo: passinfo1,//PassInfo: string(passinfo),}if err := c.WriteJSON(startMsg); err != nil {log.Printf("[%s] start err: %s", requestId, err.Error())return}log.Printf("[%s] send: %+v", requestId, startMsg)// 2. async read server messageticker := time.NewTicker(65 * time.Minute)defer ticker.Stop()exit := make(chan bool, 1)go func() {defer func() {exit <- true}()for {select {case <-ticker.C:log.Printf("[%s] exit by ticker", requestId)returndefault:_, message, err := c.ReadMessage()if err != nil {log.Printf("[%s] ReadMessage: %s", requestId, err.Error())return}log.Printf("[%s] recv: %s", requestId, message)var respMsg ResponseMessagejson.Unmarshal(message, &respMsg)if respMsg.Type == "ELR" {return}}}}()// 3. send audio binary message (file)br := bufio.NewReader(r)data := make([]byte, 640)cumulativeReadSize := 0readStartTime := time.Now()for {rbytes, err := br.Read(data)if err != nil {if errors.Is(err, io.EOF) {log.Printf("[%s] EOF", requestId)break} else {log.Printf("[%s] read err: %s", requestId, err.Error())return}}cumulativeReadSize += rbyteslog.Printf("[%s] cumulative read size: %d", requestId, cumulativeReadSize)if err := c.WriteMessage(websocket.BinaryMessage, data[:rbytes]); err != nil {log.Printf("[%s] write: %s", requestId, err.Error())return}// control sending speed (640Bytes / 20ms)for cumulativeReadSize > 32*int(time.Now().Sub(readStartTime).Milliseconds()) {time.Sleep(20 * time.Millisecond)}}// 4. send recogEnd messageendMsg := RecogEnd{Type: "recogEnd"}if err := c.WriteJSON(endMsg); err != nil {log.Printf("[%s] end err: %s", requestId, err.Error())return}log.Printf("[%s] send: %+v", requestId, endMsg)<-exit}
응답
- 음성 API 서버가 전달하는 메시지 예제입니다.
{"type": "ready","sessionId": "${SESSION_ID}"}
동기 인식 방식은 개발 및 테스트 전용입니다. 실제 서비스에는 웹 소켓 또는 비동기 방식을 사용해야 합니다. 음성 데이터 파일의 발화 길이는 30초 이내로 제한할 것을 권장합니다.
짧은 발화 내용을 인식해 문자로 변환합니다. 동기 방식으로, 발화 내용이 담긴 음성 파일을 업로드한 후 결과를 응답받기까지 네트워크 연결을 유지합니다. 요구사양에서 지원하는 데이터 포맷을 확인하고 사용해야 합니다.
헤더에 REST API 키를 담아 POST로 요청합니다. 요청 시 음성 데이터 파일을 반드시 포함해야 합니다.
요청 성공 시 응답은 음성 인식 결과를 담은 JSON 객체를 포함합니다. 이어서 음성 인식 종료(endLongRecognition) 메시지를 담은 JSON 객체가 전달되고 네트워크 연결이 종료됩니다.
| 이름 | 설명 | 필수 |
|---|---|---|
| Authorization | Authorization: KakaoAK ${REST_API_KEY}인증 방식, REST API 키로 인증 요청 | O |
| Content-Type | Content-Type: multipart/form-data요청 데이터 타입 | O |
| X-DSS-Recognition-Format | X-DSS-Recognition-Format: ${CODEC}/${BIT_DEPTH}/${SAMPLE_RATE}/${CHANNEL}/_/_CODEC: RAWPCM, MP3, AAC 중 하나BIT_DEPTH: 16으로 고정SAMPLE_RATE: RAWPCM 코덱의 경우 16000 또는 8000, MP3 또는 AAC 코덱의 경우 24000 또는 16000 중 하나중요: 웹 소켓 방식은 RAWPCM 코덱만 지원, 코덱별 음원 정보는 사양 참고참고: X-DSS-Recognition-Format: RAWPCM/16/16000/1/_/_ 사용 권장 | O |
| X-DSS-Final-Extra-Info | X-DSS-Final-Extra-Info: ${BOOLEAN}음성 인식 시작과 종료 시간 정보를 추가 제공받도록 설정 (기본값: false) | X |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| audio | File | 음성 데이터 파일 | O |
| 이름 | 설명 | 필수 |
|---|---|---|
| Content-Type | Content-Type: application/json응답 데이터 타입 | O |
| x-metering-count | 소진한 쿼터 수치 | O |
| x-request-id | 각 요청에 대한 내부 식별자 | O |
| x-stt-session-id | 음성 인식 실패 시 확인을 위한 세션 ID(Session ID) | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| finalResult | FinalResult | 최종 결과 동기 인식 시에는 항상 최종 결과만 반환됨, 파일 업로드 방식 동작 과정 참고 | X |
| errorCalled | ErrorCalled | 음성 인식 시 에러가 발생한 경우, 에러 정보 | X |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| type | String | 요청 처리 상태 타입 메시지, 아래 중 하나
| O |
| value | String | 요청 시 전달된 음성 데이터 파일에 대한 음성 인식 최종 결과 | O |
| durationMS | Int | 최종 결과 응답 시까지 전달된 음성의 총 길이(단위: ms) | X |
| x-metering-count | Int | 소진한 쿼터 수치 | O |
| nBest | NBest | 최종 인식 결과 정보(최대 10개) | X |
요청
- 헤더
- 음성 데이터 파일 포맷(
X-DSS-Recognition-Format): MP3
- 음성 데이터 파일 포맷(
curl -v -X POST "https://prod-newtone-api.i.kakao.com/v2/ai/newtone-recognize/sync" \-H "Authorization: KakaoAK ${REST_API_KEY}" \-H "Content-Type: multipart/form-data" \-H "X-DSS-Recognition-Format: MP3/16/16000/1/_/_" \-F "audio=@${FILE_NAME}"
응답
// HTTP/2 200// x-metering-count: 3// x-request-id: 53b3e75b9b9d79ad14334314daff49bb// x-stt-session-id: 6769e9f0bb8c738e0e2b2945170d96d8aa080480{"type":"finalResult","value":"헤이 카카오 처음 뵙겠습니다","durationMS":3920,"x-metering-count":3,"nBest":[{"value":"헤이 카카오 처음 뵙겠습니다","resultInfo":null,"score":0}],"voiceProfile":{"authenticated":false},"qmarkScore":31,"gender":0,"male_score":0,"female_score":0}{"type":"endLongRecognition","value":"ELR"}
비동기 인식: 파일 업로드 API를 사용하려면 음성 인식 합성 API 및 라이브러리 아지트에서 사전 협의가 필요합니다. 서비스의 규모에 따라 별도의 스토리지 또는 Redis를 사용해야 할 수 있으며, 이 경우 음성 API의 추가 구현이 필요합니다.
긴 발화 내용을 인식해 문자로 변환합니다. 비동기 방식으로, 발화 내용이 담긴 음성 파일을 업로드해 요청합니다. 음성 파일 업로드 상태 조회 후, 인식 종료된 결과 파일을 다운로드할 수 있습니다. 요구사양에서 지원하는 데이터 포맷을 확인하고 사용해야 합니다.
헤더에 REST API 키를 담아 POST로 요청합니다. 요청 시 음성 데이터 파일을 반드시 포함해야 합니다.
요청 성공 시 응답은 파일 업로드 결과를 담은 JSON 객체를 포함합니다.
| 이름 | 설명 | 필수 |
|---|---|---|
| Authorization | Authorization: KakaoAK ${REST_API_KEY}인증 방식, REST API 키로 인증 요청 | O |
| Content-Type | Content-Type: multipart/form-data요청 데이터 타입 | O |
| X-DSS-Recognition-Format | X-DSS-Recognition-Format: ${CODEC}/${BIT_DEPTH}/${SAMPLE_RATE}/${CHANNEL}/_/_CODEC: RAWPCM, MP3, AAC 중 하나BIT_DEPTH: 16으로 고정SAMPLE_RATE: RAWPCM 코덱의 경우 16000 또는 8000, MP3 또는 AAC 코덱의 경우 24000 또는 16000 중 하나중요: 웹 소켓 방식은 RAWPCM 코덱만 지원, 코덱별 음원 정보는 사양 참고참고: X-DSS-Recognition-Format: RAWPCM/16/16000/1/_/_ 사용 권장 | O |
| X-DSS-Final-Extra-Info | X-DSS-Final-Extra-Info: ${BOOLEAN}음성 인식 시작과 종료 시간 정보를 추가 제공받도록 설정 (기본값: false) | X |
| X-Tenth2-Folder-Name | X-Tenth2-Folder-Name: ${FOLDER_NAME}결과 파일 저장 폴더 이름 중요: 음성 인식 합성 API 및 라이브러리 아지트에서 별도 협의 후 사용 가능 | X |
| X-Result-File-Encrypt | X-Result-File-Encrypt: ${BOOLEAN}결과 파일 저장 시 암호화 여부 설정 중요: 음성 인식 합성 API 및 라이브러리 아지트에서 별도 협의 후 사용 가능 | X |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| audio | File | 음성 데이터 파일 | O |
| 이름 | 설명 | 필수 |
|---|---|---|
| x-request-id | 각 요청에 대한 내부 식별자 | O |
| x-stt-session-id | 음성 파일 업로드 상태 조회를 위한 세션 ID(Session ID) | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| code | String | 파일 업로드 결과 코드, 아래 중 하나
| O |
| result | String | 결과 파일 다운로드 URL 중요: 음성 데이터 파일의 크기에 따라 처리 시간이 길게 소요될 수 있으므로, 음성 파일 업로드 상태 조회로 인식 종료 여부 확인 후 다운로드 권장 | O |
요청
- 헤더
- 음성 데이터 파일 포맷(
X-DSS-Recognition-Format): RAWPCM
- 음성 데이터 파일 포맷(
curl -v -X POST "https://prod-newtone-api.i.kakao.com/v2/ai/newtone-recognize/resultfile" \-H "Authorization: KakaoAK ${REST_API_KEY}" \-H "Content-Type: multipart/form-data" \-H "X-DSS-Recognition-Format: RAWPCM/16/16000/1/_/_" \-F "audio=@${FILE_NAME}"
응답
// HTTP/2 200// x-request-id: ${X_REQUEST_ID}// x-stt-session-id: ${X_STT_SESSION_ID}{"code": "OK","result": "${URL}"}
음성 인식을 위해 업로드한 음성 파일의 분석 상태를 확인합니다. 비동기 인식: 파일 업로드 시 사용합니다.
헤더에 REST API 키를 담아 POST로 요청합니다. 헤더에 파일 업로드 시 응답으로 받은 x-stt-session-id를 전달해야 합니다.
요청 성공 시 응답은 파일 업로드 결과를 포함합니다. 파일 업로드 결과가 인식 종료인 경우, 결과 파일 다운로드로 음성 데이터 파일에 대한 음성 인식 최종 결과를 확인할 수 있습니다. 결과 파일은 .txt 형식입니다.
| 이름 | 설명 | 필수 |
|---|---|---|
| Authorization | Authorization: KakaoAK ${REST_API_KEY}인증 방식, REST API 키로 인증 요청 | O |
| X-Stt-Session-Id | X-Stt-Session-Id: ${X_STT_SESSION_ID}음성 파일 업로드 상태 조회를 위한 세션 ID(Session ID) 비동기 인식: 파일 업로드 응답으로 반환받은 값 사용 | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| code | String | 인식 동작 상태 코드 | O |
| status | String | 인식 동작 상태 텍스트 | O |
요청
- 헤더
- 세션 ID(
X-Stt-Session-Id)
- 세션 ID(
curl -v -X GET "https://prod-newtone-api.i.kakao.com/v2/ai/newtone-recognize/getStatus" \-H "Authorization: KakaoAK ${REST_API_KEY}" \-H "X-Stt-Session-Id: ${X_STT_SESSION_ID}"
응답
// HTTP/2 404{"code": "OK","status": "FINISH"}
주어진 문장을 음성으로 변환합니다. 원하는 목소리나 읽기 규칙을 설정할 수 있습니다. 요구사양에서 지원하는 데이터 포맷을 확인하고 사용해야 합니다.
헤더에 REST API 키를 담아 POST로 요청합니다. 요청 데이터 타입은 Content-Type: application/xml로 지정합니다. 음성 합성할 내용을 담은 SSML 문자열을 본문(Body)에 전달해야 합니다. 음성 데이터를 파일로 반환받으려면 요청 끝에 ${RESULT_FILE}.mp3 형식으로 파일 이름을 지정해야 합니다. 예제를 참고합니다.
요청 성공 시 응답은 SSML 내용에 따라 합성된 음성 데이터입니다. 음성 데이터는 요청 시 지정한 파일 이름과 형식으로 반환되고, 요청 경로에 자동 저장됩니다.
| 이름 | 설명 | 필수 |
|---|---|---|
| Authorization | Authorization: KakaoAK ${REST_API_KEY}인증 방식, REST API 키로 인증 요청 | O |
| Content-Type | Content-Type: application/xml요청 데이터 타입 | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| - | String | 음성 합성할 내용을 담은 SSML 문자열 사용 가능한 태그와 속성 정보는 활용하기 참고 | O |
| 이름 | 설명 | 필수 |
|---|---|---|
| x-request-id | 각 요청에 대한 식별자 | O |
| x-tts-session-id | 각 요청에 대한 내부 식별자 | O |
| x-tts-text | 요청 텍스트 | O |
| x-tts-length | 요청 텍스트 길이 | O |
| 이름 | 타입 | 설명 | 필수 |
|---|---|---|---|
| RESULT_FILE | File | 음성 데이터 파일 요청을 보낸 경로에 자동 저장됨 (예: ${USER}/Documents 경로에서 요청 시, 음성 데이터는 ${USER}/Documents 하위에 저장됨) | O |
요청
curl -v -X POST "https://prod-newtone-api.i.kakao.com/v2/ai/newtone-synthesize" \-H "Authorization: KakaoAK ${REST_API_KEY}" \-H "Content-Type: application/xml" \-d "<speak><voice name="Summer">안녕</voice></speak>" \> ${RESULT_FILE}.mp3
응답
HTTP/2 200date: Thu, 19 Sep 2024 02:08:54 GMTcontent-type: audio/mpegnewtoneversion: v.1.9.2vary: Originx-request-id: 9d0ff84e11ca689f3f217492073f4610x-tts-length: 3x-tts-session-id: 3b9e06eb38db8386314492e431def46ed6ec7195x-tts-text: %EC%8B%A0%EB%82%9C%EB%8B%A4strict-transport-security: max-age=31536000; includeSubDomains<binary audio data written to ${RESULT_FILE}.mp3>