> ## Documentation Index
> Fetch the complete documentation index at: https://docs.telloai.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 오류

> REST API 오류 코드 40종의 HTTP 상태, 의미, 대처 방법과 재시도 규칙을 확인해요.

## 오류 응답

REST 오류는 아래 봉투로 와요. **분기는 `error`와 HTTP 상태 코드로 하세요.** `message`는
표시용이고, 문구를 비교해 제어 흐름을 정하지 마세요.

```json theme={null}
{
  "statusCode": 409,
  "message": "The account is using all of its concurrent call lines",
  "error": "concurrent_limit_exceeded",
  "data": null
}
```

`data`는 보통 `null`이에요. `missing_variables`일 때는
`{ "missingVariables": ["고객명"] }`처럼 빠진 이름 목록이 와요.

## 전체 코드

### 요청·인증

| HTTP | `error` | 의미 | 대처 |
| - | - | - | - |
| `400` 또는 `415` | `invalid_request` | 본문이 JSON 객체가 아니거나 JSON이 깨졌어요. 전송 중단·잘못된 경로 인코딩은 `400`, 지원하지 않는 본문 charset·encoding은 `415`예요 | JSON 객체와 `Content-Type: application/json`, 본문 인코딩, URL 인코딩을 확인하세요 |
| `400` | `target_required` | `agentId`·`crewId`가 둘 다 있거나 둘 다 없어요 | 정확히 하나만 넣으세요 |
| `400` | `to_required` | `to`가 없거나 비어 있거나 문자열이 아니에요 | 수신번호를 문자열로 넣으세요 |
| `400` | `invalid_idempotency_key` | `Idempotency-Key`가 1\~255자가 아니거나 쉼표가 있어요. 같은 헤더를 여러 번 보낸 경우도 포함해요 | 쉼표 없는 키 하나를 헤더 한 줄로 보내세요 |
| `400` | `idempotency_key_required` | [통화 전환](https://docs.telloai.io/developer/rest/transfer-call.md)에 `Idempotency-Key`가 없어요 | 전환마다 고유한 키를 넣으세요 |
| `400` | `invalid_transfer_request` | 전환 본문의 `mode`나 `destination.type`이 없거나 문자열이 아니에요. `destination`이 객체가 아니거나 `target`이 8\~15자리 전화번호 문자열이 아닐 때도 이 오류예요 | [전환 파라미터](https://docs.telloai.io/developer/rest/transfer-call.md#파라미터)와 [번호 규칙](https://docs.telloai.io/developer/rest/transfer-call.md#번호-규칙)을 확인하세요 |
| `400` | `invalid_query` | 목록 쿼리의 형식·범위가 잘못됐어요 | `limit`, 상태 7개, 대상 id, 날짜·시간대와 오프셋 `+`의 `%2B` 인코딩을 확인하세요 |
| `400` | `invalid_cursor` | 이 API가 돌려준 형식의 커서가 아니에요 | 이전 응답의 `nextCursor`를 그대로 쓰세요 |
| `401` | `unauthenticated` | 키가 없거나 잘못됐거나 폐기됐거나 계정이 비활성이에요 | 서버용 API 키와 `Authorization: Bearer <API_KEY>`를 확인하세요 |
| `404` | `route_not_found` | `/v1` 아래 존재하지 않는 경로예요 | 메서드와 엔드포인트 경로를 확인하세요 |
| `413` | `payload_too_large` | 요청 본문이 100KiB 제한을 넘었어요 | 불필요한 본문을 줄이고 변수 개수·길이 제한을 확인하세요 |
| `422` | `invalid_variables` | `variables`가 객체가 아니거나 이름이 비었거나 점이 있어요. 값 타입·개수 50개·값 길이 200자 규칙을 어겨도 이 오류예요 | [변수 규칙](https://docs.telloai.io/developer/rest/create-call.md#통화-시작-값)에 맞춰 수정하세요 |
| `422` | `transfer_mode_unsupported` | 지원하지 않는 전환 방식이에요 | `mode`는 `"cold"`만 지원해요 |
| `422` | `transfer_destination_unsupported` | 지원하지 않는 전환 대상 종류예요 | `destination.type`은 `"phone"`만 지원해요 |

깨진 JSON·본문 크기·인코딩·없는 경로 오류는 인증보다 먼저 응답할 수 있어요. 이런 요청으로는
발신하지 않아요.

### 대상·필수 값

| HTTP | `error` | 의미 | 대처 |
| - | - | - | - |
| `404` | `agent_not_found` | 이 계정에 해당 에이전트가 없어요. 다른 계정·삭제된 대상·잘못된 id 형식도 같아요 | `/v1/agents`에서 받은 id를 `agentId`로 보내세요 |
| `404` | `crew_not_found` | 이 계정에 해당 크루가 없어요. 다른 계정·삭제된 대상·잘못된 id 형식도 같아요 | `/v1/crews`에서 받은 id를 `crewId`로 보내세요 |
| `404` | `publication_not_found` | 통화에 쓸 운영 발행본을 확인할 수 없어요 | 포털에서 배포·운영 반영 상태를 확인하세요. 계속되면 지원팀에 문의하세요 |
| `422` | `agent_inactive` | 에이전트가 배포 상태가 아니거나 운영에 반영된 판이 없어요 | 에이전트를 배포하고 운영에 반영하세요 |
| `422` | `crew_inactive` | 크루에 운영에 반영된 판이 없어요 | 크루를 배포하고 운영에 반영하세요 |
| `422` | `publication_revoked` | 운영에 반영했던 판이 내려갔어요 | 유효한 판을 운영에 다시 반영하세요 |
| `422` | `missing_variables` | 크루가 요구하는 통화 시작 값이 없거나 비어 있어요 | `data.missingVariables`의 이름을 `variables`에 채우세요. 발신되지 않았으므로 같은 멱등 키로 다시 요청할 수 있어요 |

### 발신 조건

| HTTP | `error` | 의미 | 대처 |
| - | - | - | - |
| `402` | `insufficient_credit` | 통화에 쓸 크레딧이 부족해요 | 크레딧을 충전한 뒤 같은 멱등 키로 다시 요청하세요 |
| `402` | `outbound_limit_exceeded` | 플랜의 이번 달 발신 시간을 다 썼어요 | 플랜·이용 한도를 확인하고 조건이 해소된 뒤 같은 키로 다시 요청하세요 |
| `409` | `concurrent_limit_exceeded` | 동시 발신 회선을 모두 사용 중이에요 | 기존 통화가 끝난 뒤 같은 키로 다시 요청하세요 |
| `409` | `duplicate_call` | 같은 번호로 이미 발신 중이에요 | 기존 통화를 확인하고 끝날 때까지 기다리세요. 이후 같은 키로 요청할 수 있어요 |
| `422` | `callee_not_verified` | 수신번호가 이 계정의 인증된 번호가 아니에요 | [수신번호 등록](https://docs.telloai.io/calls/caller-id.md)과 현재 플랜의 발신 조건을 확인하세요 |
| `422` | `destination_blocked` | 발신이 금지된 번호예요 | 허용된 수신번호인지 확인하고 요청을 수정하세요 |
| `422` | `caller_number_unavailable` | 계정에서 사용할 발신번호를 정할 수 없어요 | [전화번호 관리](https://docs.telloai.io/calls/numbers.md)에서 발신번호 설정을 확인하세요 |
| `422` | `call_rejected` | 요청 검증이나 그 밖의 발신 정책으로 거절됐어요 | 변수 이름 규칙과 크루 구성을 포함해 요청·설정을 확인하세요. 해결되지 않으면 지원팀에 문의하세요 |

이 표의 거절은 모두 **발신 전**이에요. 오류 응답을 24시간 저장하지 않으므로 원인을 해결한
뒤 같은 멱등 키로 다시 요청할 수 있어요.

### 멱등 키·통화 제어

| HTTP | `error` | 의미 | 대처 |
| - | - | - | - |
| `409` | `idempotency_key_reused` | 같은 계정에서 이미 사용한 멱등 키에 다른 요청을 보냈어요. 통화 생성과 전환은 같은 키 공간을 써요 | 앞선 작업의 재시도면 같은 본문을 보내세요. 별개의 새 통화나 새 전환에만 새 키를 쓰세요 |
| `409` | `idempotency_in_progress` | 같은 키의 요청이 아직 처리 중이에요 | 새 키로 바꾸지 말고 잠시 뒤 같은 키·같은 본문으로 다시 확인하세요 |
| `404` | `call_not_found` | 없는 통화·다른 계정의 통화·잘못된 id 형식이에요. 전환 파생 통화·테스트 통화도 조회·제어 대상이 아니에요 | 현재 계정의 목록이나 생성 응답에서 받은 `c_숫자` 형식 id를 쓰세요 |
| `409` | `call_not_active` | 이미 끝난 통화를 종료하거나 전환하려고 했어요 | 상세에서 최종 상태와 결과를 확인하세요 |
| `409` | `call_not_in_progress` | 통화 중(`inProgress`)이 아닌 통화를 전환하려고 했어요. 아직 발신 중(`dialing`)인 경우가 대표적이에요 | 상대가 받아 `inProgress`가 된 뒤 다시 요청하세요 |
| `409` | `call_control_unsupported` | 진행 중이지만 REST로 종료할 수 없는 출처의 통화예요 | `source`를 확인하세요. 종료 엔드포인트는 `api`·`a2a`·`sdk`만 지원해요. 전환은 출처와 관계없이 돼요 |

### 서비스 처리

| HTTP | `error` | 의미 | 대처 |
| - | - | - | - |
| `500` | `internal_error` | 요청 처리 중 예상하지 못한 오류가 났어요 | 생성 요청의 발신 전 거절은 저장하지 않아요. 잠시 뒤 같은 멱등 키로 다시 시도하고, 계속되면 지원팀에 문의하세요 |
| `502` | `call_outcome_unknown` | 생성 요청을 보냈지만 발신 결과를 확인하지 못했어요. 통화가 시작됐을 수 있어요 | **통화 목록에서 확인하기 전에는 새 키로 재발신하지 마세요.** 같은 키는 저장된 `502`를 재생해요 |
| `503` | `call_record_unavailable` | 통화 기록을 만들지 못해 발신하지 않았어요 | 잠시 뒤 같은 멱등 키로 다시 요청하세요 |
| `503` | `voice_gateway_unavailable` | 통화 서비스가 지금 요청을 받을 수 없어요. 통화 생성이면 발신하지 않았어요. 통화 전환이면 드물게 늦게 전달돼 전환될 수 있어요 | 잠시 뒤 같은 멱등 키로 다시 요청하세요. 전환은 먼저 [통화 상세](https://docs.telloai.io/developer/rest/get-call.md)를 확인하세요 |
| `503` | `credit_check_unavailable` | 크레딧 정보를 확인하지 못했어요. 잔액 부족을 뜻하지 않아요 | 잠시 뒤 같은 멱등 키로 다시 요청하세요 |

## 재시도와 멱등 응답

[통화 생성](https://docs.telloai.io/developer/rest/create-call.md#중복-발신-방지)에 `Idempotency-Key`를 보내면 계정
범위로 **`201`과 `502 call_outcome_unknown`만 24시간 저장**해요. 정규화 후 같은 요청을 같은
키로 보내면 저장된 상태 코드·본문을 그대로 돌려주고 추가 발신하지 않아요.
[통화 전환](https://docs.telloai.io/developer/rest/transfer-call.md#중복-전환-방지)은 키가 필수이고 `202`만 저장해요. 두 요청은
같은 계정 범위 키 공간을 쓰니 통화 생성과 전환에 같은 키를 쓰지 마세요.

다른 발신 전 거절은 `4xx`든 `5xx`든 저장하지 않아요. 입력·설정을 고치거나 일시적인 조건이
해소된 뒤 **같은 키로** 다시 요청할 수 있어요. `idempotency_key_reused`·
`idempotency_in_progress`는 기존 요청의 키를 해제하거나 덮어쓰지 않아요.

> [!WARNING]
>
> `call_outcome_unknown`은 단순한 재발신 신호가 아니에요. [통화 목록](https://docs.telloai.io/developer/rest/list-calls.md)에서
> 대상·생성 시각을 확인하고, 발신 여부를 판단한 뒤에만 새 요청을 결정하세요. 목록을 확인하지
> 않고 새 키로 다시 걸면 두 번 발신될 수 있어요.

## 관련 문서

* [개요·인증](https://docs.telloai.io/developer/rest/overview.md)
* [통화 생성](https://docs.telloai.io/developer/rest/create-call.md)
* [통화 목록](https://docs.telloai.io/developer/rest/list-calls.md)
* [통화 종료](https://docs.telloai.io/developer/rest/end-call.md)
* [통화 전환](https://docs.telloai.io/developer/rest/transfer-call.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.