# 이메일 조회 (보낸 것·받은 것) (/docs/api/emails/listEmails)
**GET /v1/accounts/{accountId}/emails**
```json
{
  "operationId": "listEmails",
  "summary": "이메일 조회 (보낸 것·받은 것)",
  "description": "이 계정의 이메일을 최신순으로 조회합니다. **보낸 것과 받은 것이 같은 목록**에 나오며\n`direction` 으로 구분합니다 — 통화·문자 조회와 같은 방식입니다.\n\n한쪽만 보려면 `direction=outbound` 또는 `direction=inbound` 를 주십시오.\n\n⚠️ 보낸 메일의 `status` 는 **공급자 접수 여부**입니다 — 수신함 도착이 아닙니다.\n전달·반송은 비동기로 확인되며 이 값은 그 뒤에도 바뀌지 않습니다.\n\n⚠️ 본문은 목록에 실리지 않습니다. 단건 조회로 받으십시오.",
  "tags": [
    "Emails"
  ],
  "parameters": [
    {
      "name": "accountId",
      "in": "path",
      "required": true,
      "schema": {
        "type": "string"
      },
      "description": "계정 ID",
      "example": "AC1a2b3c4d"
    },
    {
      "name": "direction",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "enum": [
          "outbound",
          "inbound"
        ]
      },
      "description": "방향 필터. **지정하지 않으면 양방향이 함께** 나옵니다.",
      "example": "inbound"
    },
    {
      "name": "status",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "enum": [
          "sending",
          "sent",
          "failed",
          "received"
        ]
      },
      "description": "상태 필터. 받은 메일은 항상 `received` 입니다.",
      "example": "failed"
    },
    {
      "name": "from",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "email"
      },
      "description": "발신 주소 필터(정확히 일치). 특정 상대와 오간 메일을 찾을 때 씁니다.",
      "example": "customer@gmail.com"
    },
    {
      "name": "recipient",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "email"
      },
      "description": "**받은 메일이 실제로 배달된 주소** 필터(정확히 일치).\n\n한 도메인에 `support@`·`sales@` 처럼 여러 주소를 두고 처리를 나눈다면 이 필터를\n쓰십시오. ⚠️ 숨은 참조(BCC)로 온 메일은 `to` 헤더에 주소가 없으므로 `to` 로는\n찾을 수 없습니다.",
      "example": "support@example.com"
    },
    {
      "name": "receivedAfter",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "date-time"
      },
      "description": "이 시각 **이상**(포함). `direction=inbound` 면 공급자가 받은 시각, 그 밖에는\n생성 시각 기준입니다.",
      "example": "2026-09-01T00:00:00Z"
    },
    {
      "name": "receivedBefore",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string",
        "format": "date-time"
      },
      "description": "이 시각 **미만**(제외).",
      "example": "2026-10-01T00:00:00Z"
    },
    {
      "name": "emailDomainId",
      "in": "query",
      "required": false,
      "schema": {
        "type": "string"
      },
      "description": "발신 도메인 필터. 검증한 도메인이 여럿일 때 씁니다.",
      "example": "clx9dom00001"
    },
    {
      "name": "page",
      "in": "query",
      "required": false,
      "schema": {
        "type": "integer",
        "default": 0
      },
      "description": "페이지 번호(0-based)",
      "example": 0
    },
    {
      "name": "pageSize",
      "in": "query",
      "required": false,
      "schema": {
        "type": "integer",
        "default": 20,
        "maximum": 100
      },
      "description": "페이지 크기(최대 100)",
      "example": 20
    },
    {
      "name": "page_size",
      "in": "query",
      "required": false,
      "deprecated": true,
      "schema": {
        "type": "integer",
        "maximum": 100
      },
      "description": "`pageSize` 의 별칭(하위호환). 신규 연동은 `pageSize` 를 사용하세요.",
      "example": 50
    },
    {
      "name": "limit",
      "in": "query",
      "required": false,
      "deprecated": true,
      "schema": {
        "type": "integer",
        "maximum": 100
      },
      "description": "`pageSize` 의 별칭(하위호환). 신규 연동은 `pageSize` 를 사용하세요.",
      "example": 100
    }
  ],
  "responses": {
    "200": {
      "description": "이메일 목록",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "description": "이메일 발송 이력 목록. 항목은 단건 조회와 **같은 모양**입니다 — 목록에서 본 필드를\n상세에서 다시 부를 필요가 없습니다.",
            "properties": {
              "data": {
                "type": "array",
                "items": {
                  "type": "object",
                  "description": "이메일 한 건. **보낸 것과 받은 것이 같은 모양**이며 `direction` 으로 구분합니다\n(통화·문자와 같은 규약입니다).\n\n방향 전용 필드는 반대 방향에서 `null` 입니다 — 받은 메일에는 `failureCode` 가,\n보낸 메일에는 `verdicts`·`recipients` 가 `null` 입니다.\n\n⚠️ **스레드 필드(`replyTo`·`inReplyTo`·`references`)는 방향 전용이 아닙니다.** 답장으로\n보낸 메일도 사슬을 가집니다. 예외는 `messageId` 하나이며, 보낸 메일에서 `null` 인\n이유는 \"해당 없음\" 이 아니라 **공급자가 그 헤더를 덮어써서 우리도 모른다**는 것입니다.",
                  "properties": {
                    "emailId": {
                      "type": "string",
                      "description": "한국AI통신 이메일 리소스 ID.",
                      "example": "clx9eml00001"
                    },
                    "direction": {
                      "type": "string",
                      "enum": [
                        "outbound",
                        "inbound"
                      ],
                      "description": "`outbound` 는 이 계정이 보낸 메일, `inbound` 는 이 계정의 **수신 도메인으로 들어온**\n메일입니다.",
                      "example": "inbound"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "sending",
                        "sent",
                        "failed",
                        "received"
                      ],
                      "description": "보낸 메일은 `sent`(공급자 접수) 또는 `failed` 입니다 — `sent` 는 **접수됐다**는\n뜻이지 수신함 도착이 아닙니다. 받은 메일은 항상 `received` 입니다.\n\n`sending` 은 발송 요청을 처리하는 중이라는 뜻입니다. 조회에서 오래 남아 있으면\n공급자 접수 직후 처리가 끊긴 건이며, 메일은 **나갔을 수 있습니다.**"
                    },
                    "from": {
                      "type": "string",
                      "description": "발신자. **보낸 메일은 RFC 5322 mailbox** 문자열입니다 — 요청에 표시명을 넣었으면\n`\"한국AI통신(고객지원)\" <hello@example.com>` 처럼 표시명과 주소를, 없었으면 주소만\n담습니다. 특수문자가 있는 표시명은 따옴표로 싸고 안의 `\"`·`\\` 는 이스케이프합니다.\n\n**받은 메일은 현재 주소만** 담습니다.",
                      "example": "\"한국AI통신(고객지원)\" <no-reply@example.com>"
                    },
                    "to": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "email"
                      },
                      "example": [
                        "customer@gmail.com"
                      ]
                    },
                    "cc": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "email"
                      },
                      "example": []
                    },
                    "bcc": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "email"
                      },
                      "example": []
                    },
                    "suppressed": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "email"
                      },
                      "description": "수신거부 명단에 있어 이 발송에서 **빠진** 주소들. 요청한 표기 그대로 돌려줍니다.\n\n⚠️ 이메일은 차단된 수신자가 있어도 **나머지에게는 보냅니다**(전화·문자가 발신 전체를\n거절하는 것과 다릅니다). 그래서 `201` 을 받고도 일부가 안 갔을 수 있고, **이 칸이 그걸\n알려주는 유일한 자리**입니다. 비어 있으면 아무도 빠지지 않았다는 뜻입니다.\n\n`recipientCount` 에는 포함되지 않습니다 — 요청한 수신자 수는\n`recipientCount + suppressed.length` 입니다. 받은 메일에서는 항상 빈 배열입니다.",
                      "example": []
                    },
                    "subject": {
                      "type": "string",
                      "nullable": true,
                      "example": "주문이 접수되었습니다"
                    },
                    "recipientCount": {
                      "type": "integer",
                      "description": "보낸 메일에서는 **과금 단위**입니다 — 실제로 발송한 To+Cc+Bcc 의 합계이며 한 통을\n3명에게 보내면 3입니다. **수신거부로 빠진 주소는 세지 않습니다**(`suppressed` 참고).\n받은 메일에서는 **이 계정에 실제로 배달된 주소 수**(`recipients` 의 길이)입니다.",
                      "example": 1
                    },
                    "attachmentCount": {
                      "type": "integer",
                      "example": 1
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "example": "2026-09-03T07:20:00.000Z"
                    },
                    "failureCode": {
                      "type": "string",
                      "nullable": true,
                      "description": "실패 사유 코드. `status` 가 `sent` 면 `null` 입니다.\n\n`provider_unavailable` 은 **공급자를 부르지 못한** 경우이고, 그 밖의 값은 공급자가\n거절한 경우입니다.",
                      "example": null
                    },
                    "failureMessage": {
                      "type": "string",
                      "nullable": true,
                      "description": "사람이 읽는 실패 설명. `status` 가 `sent` 면 `null` 입니다.",
                      "example": null
                    },
                    "replyTo": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "format": "email"
                      },
                      "description": "답장 주소(`Reply-To`). 받은 메일은 발신자가 지정한 주소, 보낸 메일은 발송할 때\n지정한 값입니다.\n\n⭐ **답장은 `from` 이 아니라 이 주소로 보내십시오.** 비어 있을 때만 `from` 이\n답장 주소입니다(RFC 5322 §3.6.2). 뉴스레터·티켓 시스템은 대부분 이 값을 다르게\n둡니다.",
                      "example": [
                        "support@example.com"
                      ]
                    },
                    "messageId": {
                      "type": "string",
                      "nullable": true,
                      "description": "이 메일 자신의 `Message-ID`(꺾쇠 `< >` 제외). **답장할 때 `inReplyTo` 에 그대로\n넣는 값입니다.**\n\n⛔ **보낸 메일은 항상 `null`** 입니다. 이 헤더는 공급자가 발급하며 우리가 지정한\n값을 덮어쓰기 때문에 우리도 그 값을 모릅니다.\n⚠️ 받은 메일도 `null` 일 수 있습니다 — 이 헤더는 RFC 상 필수가 아니고, 붙이지 않고\n보내는 발신자가 실제로 있습니다. 그 메일에는 스레드로 답장할 수 없습니다.",
                      "example": "CAF7n8xW1p_abc@mail.gmail.com"
                    },
                    "inReplyTo": {
                      "type": "string",
                      "nullable": true,
                      "description": "이 메일이 답장한 원본의 `Message-ID`(꺾쇠 제외). 답장이 아니면 `null` 입니다.",
                      "example": null
                    },
                    "references": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "대화의 조상 사슬. **오래된 것이 앞**입니다. 다음 답장에 넘길 값은\n`[...references, messageId]` 입니다.\n\n⚠️ 보낸 메일의 값은 요청하신 목록이 아니라 **실제로 헤더에 실어 보낸 목록**입니다.\n긴 대화는 공급자 헤더 길이 상한 때문에 RFC 5537 §3.4.4 에 따라 첫 항목과 최근\n항목만 남기고 줄여 보냅니다.",
                      "example": [
                        "CAF7n8xW1p_xyz@mail.gmail.com",
                        "CAF7n8xW1p_abc@mail.gmail.com"
                      ]
                    },
                    "recipients": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "string",
                        "format": "email"
                      },
                      "description": "**실제로 이 계정에 배달된 주소.** 받은 메일에만 있습니다(보낸 메일은 `null`).\n\n⚠️ **`to` 를 보고 라우팅하지 마십시오.** 숨은 참조(BCC)로 온 메일은 `to` 에 그\n주소가 **없습니다** — 이 필드에만 있습니다. 한 도메인에 `support@`·`sales@` 처럼\n여러 주소를 두고 처리를 나눈다면 반드시 이 값을 쓰십시오.",
                      "example": [
                        "support@example.com"
                      ]
                    },
                    "receivedAt": {
                      "type": "string",
                      "format": "date-time",
                      "nullable": true,
                      "description": "공급자가 메일을 받은 시각. 받은 메일에만 있습니다.",
                      "example": "2026-09-04T05:48:00.000Z"
                    },
                    "sizeBytes": {
                      "type": "integer",
                      "nullable": true,
                      "description": "받은 메일의 원문 크기(바이트). ⚠️ 공급자가 덧붙인 헤더(약 3.6KB)가 포함된 값이라\n메일 클라이언트가 보여 주는 크기와 다를 수 있습니다. **과금은 이 값 기준입니다.**",
                      "example": 4030
                    },
                    "verdicts": {
                      "type": "object",
                      "nullable": true,
                      "description": "공급자의 스팸·바이러스·인증 판정. 받은 메일에만 있습니다.\n\n⚠️ **값은 공급자 원문 그대로**입니다(`PASS`·`FAIL`·`GRAY`·`PROCESSING_FAILED` 등).\n우리가 해석하지 않으므로 목록이 늘어날 수 있습니다 — 모르는 값을 만나면 안전한\n쪽으로 처리하십시오.\n\n⛔ **`from` 만 믿고 자동 처리하지 마십시오.** 발신자는 위조될 수 있고, 그걸\n판별하라고 `spf`·`dkim`·`dmarc` 를 함께 드립니다.",
                      "properties": {
                        "spam": {
                          "type": "string",
                          "nullable": true,
                          "example": "PASS"
                        },
                        "virus": {
                          "type": "string",
                          "nullable": true,
                          "example": "PASS"
                        },
                        "spf": {
                          "type": "string",
                          "nullable": true,
                          "example": "PASS"
                        },
                        "dkim": {
                          "type": "string",
                          "nullable": true,
                          "example": "PASS"
                        },
                        "dmarc": {
                          "type": "string",
                          "nullable": true,
                          "example": "GRAY"
                        }
                      }
                    },
                    "parseStatus": {
                      "type": "string",
                      "nullable": true,
                      "enum": [
                        "parsed",
                        "unparsable",
                        null
                      ],
                      "description": "받은 메일의 본문 해석 결과. `unparsable` 이면 본문을 읽지 못한 것이며, 그때도\n원문은 그대로 보관되어 단건 조회의 `raw` 로 받을 수 있습니다.",
                      "example": "parsed"
                    }
                  },
                  "required": [
                    "emailId",
                    "direction",
                    "status",
                    "from",
                    "to",
                    "recipientCount",
                    "createdAt"
                  ]
                }
              },
              "meta": {
                "type": "object",
                "properties": {
                  "page": {
                    "type": "integer",
                    "description": "0-based 페이지 번호.",
                    "example": 0
                  },
                  "pageSize": {
                    "type": "integer",
                    "example": 20
                  },
                  "total": {
                    "type": "integer",
                    "description": "필터를 적용한 전체 건수.",
                    "example": 137
                  }
                },
                "required": [
                  "page",
                  "pageSize",
                  "total"
                ]
              }
            },
            "required": [
              "data",
              "meta"
            ]
          }
        }
      }
    },
    "400": {
      "description": "`page`·`pageSize` 가 정수가 아님.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "401": {
      "description": "인증 실패",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "403": {
      "description": "접근 권한 없음",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string",
                "description": "사람이 읽을 수 있는 에러 메시지"
              },
              "code": {
                "type": "string",
                "description": "기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서\n바뀔 수 있지만 코드는 계약입니다.\n\n같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는\n  - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서\n    해제해야 발신됩니다.\n  - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다.\n\n전화번호 정규화 관련:\n  - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님)\n  - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)",
                "example": "recipient_blocked"
              },
              "ip": {
                "type": "string",
                "description": "`overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다.\n해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔\n「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.",
                "example": "52.79.213.41"
              },
              "processedAt": {
                "type": "string",
                "format": "date-time",
                "description": "문자 발송 요청을 거부한 서버가 오류 응답을 생성한 시각(UTC). 콘솔은 이 값을 한국 시각으로 표시합니다. 인증·요청 형식 검증 등 발송 서비스 진입 전 오류에는 없을 수 있습니다.",
                "example": "2026-10-21T04:10:34.303Z"
              },
              "blockers": {
                "type": "array",
                "description": "`certificate_not_eligible` 일 때만 옵니다. 발급할 수 없는 번호와 그 이유입니다.",
                "items": {
                  "type": "object",
                  "description": "번호 하나가 발급되지 않는(또는 안내가 필요한) 이유.\n\n| code | 뜻 | 발급 |\n|---|---|---|\n| `number_not_owned` | 이 계정이 보유한 번호가 아님(반납·재배정 포함) | 막힘 |\n| `number_not_carrier_issued` | 한국AI통신이 개통한 070·대표번호가 아님(모바일 게이트웨이, 타사 번호) | 막힘 |\n| `business_info_incomplete` | 사업자 계정인데(관리번호 제외) 상호·사업자등록번호·대표자명·사업장 주소 중 빈 칸 | 막힘 |\n| `identity_unverified` | 개인 계정 번호 또는 관리번호인데 그 번호에 본인확인 정보가 없음 | 막힘 |\n| `account_restricted` | 이용 제한 계정 | 막힘 |\n| `business_recheck_pending` | 사업자 계정인데 사업자 정보 재확인이 진행 중(통과 전) — 관리번호를 뺀 계정의 모든 번호 | 막힘 |\n| `holder_is_personal` | 개인 명의로 찍힌다는 안내 | 가능 |",
                  "properties": {
                    "number": {
                      "type": "string",
                      "description": "422 응답의 blockers 에만 있다",
                      "example": "07012340002"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "number_not_owned",
                        "number_not_carrier_issued",
                        "business_info_incomplete",
                        "identity_unverified",
                        "account_restricted",
                        "business_recheck_pending",
                        "holder_is_personal"
                      ],
                      "example": "number_not_carrier_issued"
                    },
                    "message": {
                      "type": "string",
                      "example": "이용증명원은 한국AI통신이 개통한 070·대표번호만 발급됩니다."
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}
```