> ## 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.

# message/send

> 통화를 시작하거나, 진행 중인 통화에 답변을 보내요.

## 할 수 있는 일

메시지를 하나 보내요. `taskId`와 역할에 따라 두 가지로 동작해요.

| 보내는 값                         | 동작                                |
| ----------------------------- | --------------------------------- |
| `taskId` 없음 · `role: "user"`  | **통화 시작.** `metadata.to`로 전화를 걸어요 |
| `taskId` 있음 · `role: "agent"` | **답변.** 그 텍스트가 통화에서 발화돼요          |

통화 진행을 실시간으로 받으려면 [message/stream](/developer/a2a/methods/message-stream)을
쓰세요. 이 메서드는 응답 한 번으로 끝나요.

## 통화 시작

```bash theme={null}
curl -X POST "https://api.telloai.io" \
  -H "Authorization: Bearer <YOUR_A2A_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "message/send",
    "params": {
      "message": {
        "role": "user",
        "parts": [{ "kind": "text", "text": "내일 14시 예약이 맞는지 확인해줘" }],
        "messageId": "msg-1",
        "metadata": { "to": "+821012345678" }
      }
    }
  }'
```

### 파라미터

| 필드                           | 필수     | 설명                                    |
| ---------------------------- | ------ | ------------------------------------- |
| `params.message.role`        | 필수     | `user`                                |
| `params.message.parts`       | 필수     | `{ kind, text }` 배열. 텍스트가 통화 목표예요     |
| `params.message.messageId`   | 필수     | 메시지 식별자                               |
| `params.message.metadata.to` | **필수** | 전화 걸 번호. E.164 형식(`+821012345678`) 권장 |

<Warning>
  `metadata.to`가 없으면 `to_required`로 거부돼요. 전화도 걸리지 않아요.
</Warning>

통화에 쓸 에이전트는 **인증 키에 묶여요.** 메시지로는 지정할 수 없어요.

### 결과

`submitted` 상태의 태스크가 와요. 이 시점엔 아직 벨이 울리기 전이에요. 응답의 `id`가 이후
답변·취소에 쓸 **taskId**예요.

## 답변

`taskId`를 넣고 역할을 `agent`로 보내요.

```bash theme={null}
curl -X POST "https://api.telloai.io" \
  -H "Authorization: Bearer <YOUR_A2A_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "message/send",
    "params": {
      "message": {
        "role": "agent",
        "parts": [{ "kind": "text", "text": "네, 14시로 확인해주세요." }],
        "messageId": "msg-2",
        "taskId": "<TASK_ID>"
      }
    }
  }'
```

세 가지가 모두 맞아야 답변으로 처리돼요.

1. `taskId`가 비어 있지 않아야 해요.
2. 역할이 `agent`여야 해요.
3. 비어 있지 않은 텍스트 파트가 있어야 해요.

하나라도 빠지면 답변이 아니라 새 메시지로 취급돼요.

## 오류

| 코드                           | 언제                          |
| ---------------------------- | --------------------------- |
| `to_required`                | 통화 시작인데 `metadata.to`가 없음   |
| `task_not_found`             | 없는 태스크                      |
| `session_principal_mismatch` | 다른 계정의 태스크                  |
| `session_not_active`         | 이미 끝난 태스크라 답변을 받지 않음        |
| `call_not_started`           | 아직 통화가 연결되지 않음. 기다렸다 다시 보내요 |
| `assistant_role_required`    | 답변 역할이 `agent`가 아님          |
| `assistant_text_required`    | 답변에 비어 있지 않은 텍스트가 없음        |

`call_not_started`는 실패가 아니라 아직 이르다는 뜻이에요. 태스크를 포기하지 말고 턴을
기다렸다 다시 보내요. 전체 목록은 [오류](/developer/a2a/errors)에 있어요.

## 주의사항

* 실제 통화가 발신되고 크레딧이 차감돼요. 통제된 테스트 수신번호로만 시험하세요.
* 이 메서드만으로는 상대 발화를 받을 수 없어요. 대화를 이어가려면
  [message/stream](/developer/a2a/methods/message-stream)이나
  [tasks/resubscribe](/developer/a2a/methods/tasks-resubscribe)로 스트림을 열어요.

## 관련 문서

* [message/stream](/developer/a2a/methods/message-stream)
* [태스크 상태](/developer/a2a/task-states)
* [외부에서 호출받기](/developer/a2a/inbound)
