> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.claw-ops.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.claw-ops.com/_mcp/server.

# 이메일 도메인 수신 MX 확인

POST https://api.claw-ops.com/v1/accounts/{accountId}/email-domains/{emailDomainId}/receiving-verification

이 도메인의 **MX 레코드를 실제로 조회**해서 수신이 우리에게 오도록 걸렸는지 판정하고,
결과를 `receivingStatus` 에 저장한 뒤 갱신된 도메인을 돌려줍니다. MX 를 심은 뒤 호출하세요.

수신이 꺼져 있으면 `422` 입니다 — 먼저 수신을 켜세요.

**판정 기준은 "우리 MX 가 있다" 가 아니라 "우리 MX 가 단독으로 가장 낮다" 입니다.**

```
10 aspmx.l.google.com     20 inbound-smtp...   → not_lowest_priority (전부 Google 로 갑니다)
10 aspmx.l.google.com     10 inbound-smtp...   → not_lowest_priority (절반씩 나뉩니다)
10 inbound-smtp...                             → verified
```

⚠️ **DNS 조회 자체에 실패하면(SERVFAIL·타임아웃) `200` 이지만 아무것도 바뀌지 않습니다.**
`receivingCheckedAt` 이 그대로면 확인하지 못한 것이니 잠시 뒤 다시 호출하세요. 조회 실패가
`verified` 를 뒤집거나 수신을 끄는 일은 없습니다. 반대로 MX 가 **없다는 것이 확인되면**
`not_found` 로 내려갑니다.

⚠️ DNS 전파에는 시간이 걸립니다(보통 수 분, TTL 에 따라 더 길 수 있음). 곧바로 `not_found`
가 나와도 정상이며, 수 분 간격으로 다시 호출하세요.

⚠️ **요청 본문은 없지만 `Content-Length: 0` 은 필요합니다.** 본문도 이 헤더도 없는 POST 는
ClawOps 에 닿기 전에 게이트웨이가 `411 Length Required` 로 거절합니다(HTML 응답이라
`{ error, code }` 형식도 아닙니다). 대부분의 HTTP 클라이언트·SDK 는 이 헤더를 자동으로
붙이지만, `curl -X POST` 는 붙이지 않습니다 — `curl -X POST -H 'Content-Length: 0' …`
또는 `curl -X POST -d '{}' …` 로 호출하세요.

Reference: https://docs.claw-ops.com/api-reference/claw-ops-api/email-domains/verify-email-domain-receiving

## Authentication

- `Authorization` header (bearer token, required) — API Key를 Bearer 토큰으로 전달

## Request

### Path parameters

- `accountId` (string, required) — 계정 ID
- `emailDomainId` (string, required) — 도메인 리소스 ID

## Response

### 200

확인 수행 완료. 조회에 성공하면 `receivingStatus`·`receivingCheckedAt` 이 갱신되고, 조회에 실패하면 저장된 값이 그대로 돌아옵니다

- `id` (string, optional) — 도메인 리소스 id. 조회·검증·삭제에 이 값을 사용합니다.
- `domain` (string, optional) — 정규화된 도메인. 대소문자·끝 점·한글 도메인(punycode 변환)이 모두 정규화되어 저장·응답됩니다. 루트 도메인과 하위 도메인은 서로 다른 리소스입니다.
- `status` (enum, optional) — pending=DNS 설정 또는 확인 대기, verified=DKIM 확인 완료(발신 가능), failed=DNS 레코드를 확인하지 못함(고객 DNS 를 고쳐야 풀립니다). **일시적인 공급자 장애로는 이 값이 내려가지 않습니다** — 그 경우 검증 요청이 503 을 반환하고 상태는 마지막 성공 결과를 유지합니다. 반대로 CNAME 을 지우면 `verified` 였던 도메인도 `failed` 로 내려갑니다. 다시 심으면 `verified` 로 돌아옵니다.
  - Allowed values: `pending`, `verified`, `failed`
- `dnsRecords` (list of EmailDomainDnsRecord, optional) — 심어야 하는 DNS 레코드. **순서는 계약이 아닙니다.** ⛔ **여기 실린 레코드가 전부 필수인 것은 아닙니다.** 각 항목의 `requirement` 를 보고 나누십시오 — `required`(DKIM CNAME 3건)를 모두 심어야 발송이 열리고, `recommended` (반송 주소 `mail_from_*` · `dmarc`)는 없어도 발송은 되며 도달률에만 영향을 줍니다. `optional` 은 그 기능을 쓸 때만 심습니다. `receivingEnabled` 가 `true` 면 여기에 수신용 MX 1건(`purpose: inbound`)이 함께 실립니다. 꺼져 있으면 실리지 않습니다 — 수신을 쓰지 않는 도메인에 MX 를 심으면 그 도메인의 메일이 전부 ClawOps 로 온 뒤 버려지기 때문입니다. ⚠️ `dmarc` 는 **이미 심어 두신 것을 우리가 확인했으면 실리지 않습니다**(`dmarcStatus` 참고). 그 값은 고객 도메인 전체의 정책이라 우리가 제안하는 시작점(`p=none`)으로 덮어쓰면 안 됩니다.
- `receivingEnabled` (boolean, optional) — 이 도메인으로 **메일을 받을지** 여부. `status` 가 `verified` 인 도메인만 켤 수 있습니다. ⚠️ 켜는 것만으로 수신되지 않습니다 — `dnsRecords` 에 나타나는 MX 를 심어야 합니다. 반대로 **끄면 MX 가 남아 있어도 받지 않습니다.** 그 경우 메일은 ClawOps 까지 도착한 뒤 버려지고 **수신 요금은 청구됩니다.** 수신을 그만둘 때는 MX 도 함께 지우세요.
- `receivingStatus` (enum, optional, nullable) — ClawOps 가 **실제로 조회한** 이 도메인의 MX 판정입니다. 수신을 켜지 않았으면 `null` 입니다. `pending`=켰지만 아직 확인하지 않음 · `verified`=우리 MX 가 있고 우선순위도 단독 최저 · `not_found`=MX 에 우리 호스트가 없음 · `not_lowest_priority`=더 낮거나 같은 우선순위의 다른 MX 가 있어 메일이 그쪽으로 가거나 나뉨 · `unsupported_region`=이 도메인이 등록된 리전은 수신을 지원하지 않음. ⚠️ **DNS 조회 자체에 실패하면 이 값은 바뀌지 않습니다.** 확인 API 가 `200` 을 주는데 `receivingCheckedAt` 이 그대로라면 조회하지 못한 것입니다 — 잠시 뒤 다시 호출하세요. 우리 쪽 일시 장애가 `verified` 를 뒤집는 일은 없습니다.
  - Allowed values: `pending`, `verified`, `not_found`, `not_lowest_priority`, `unsupported_region`
- `receivingCheckedAt` (datetime, optional, nullable) — MX 를 마지막으로 **실제 조회한** 시각. 조회에 실패하면 갱신되지 않습니다.
- `mailFromStatus` (enum, optional, nullable) — 반송 주소(`mail_from_*` 레코드)가 실제로 섰는지. 아직 시도한 적이 없으면 `null` 입니다. `pending`=레코드를 찾는 중 · `verified`=반송 주소가 내 도메인으로 섭니다 · `failed`=탐지를 포기했습니다(레코드를 심고 검증 API 를 다시 호출하면 재설정됩니다). ⛔ **`status` 와 다른 축입니다.** 이 값이 `pending` 이나 `failed` 여도 **메일은 정상 발송됩니다** — 반송 주소만 ClawOps 기본값으로 돌아갈 뿐입니다. 발송 가능 여부는 `status` 로 판단하십시오.
  - Allowed values: `pending`, `verified`, `failed`
- `dmarcStatus` (enum, optional, nullable) — ClawOps 가 **실제로 조회한** 이 도메인의 DMARC 정책입니다. 아직 조회한 적이 없으면 `null` 입니다(검증 API 를 호출하면 채워집니다). `not_found`=레코드가 없거나 `p` 태그가 없어 무효 · `spf_strict`=`aspf=s` 가 걸려 있음 · `monitor`=`p=none` · `enforced`=`p=quarantine` 또는 `p=reject`. ⛔ **`spf_strict` 는 조치가 필요합니다.** 반송 주소(`mail_from_*`)를 모두 심어도 `aspf=s` 가 있으면 SPF 정렬이 서지 않아 그 설정이 **아무 효과도 내지 못합니다.** 그런데 메일은 계속 발송되고 DKIM 으로 DMARC 도 통과하므로, 이 값을 보지 않으면 알 방법이 없습니다. `aspf=s` 를 빼시면 됩니다(기본값이 relaxed 이고, 그때 정렬이 섭니다). ⚠️ **DNS 조회 자체에 실패하면 이 값은 바뀌지 않습니다** — `receivingStatus` 와 같은 규칙입니다. 그리고 이 값은 **발송을 막지 않습니다.** DMARC 는 고객 도메인의 정책이지 ClawOps 의 요구사항이 아닙니다.
  - Allowed values: `not_found`, `spf_strict`, `monitor`, `enforced`
- `lastCheckedAt` (datetime, optional, nullable) — 공급자 상태를 마지막으로 실제 조회한 시각. 조회 자체가 실패하면 갱신되지 않습니다.
- `verifiedAt` (datetime, optional, nullable) — **최초로** 검증된 시각. 이후 DKIM 이 깨졌다가 복구되어도 이 값은 바뀌지 않습니다. 지금 발신 가능한지는 `status` 로 판단하세요.
- `pendingExpiresAt` (datetime, optional, nullable) — ⚠️ **이 시각까지 검증을 마치지 않으면 다른 계정이 이 도메인을 등록할 수 있습니다.** 한 도메인은 ClawOps 전체에서 한 계정만 소유하는데, 등록만 해두고 소유를 증명하지 않은 도메인이 그 자리를 무기한 붙들면 실제 소유자가 등록할 방법이 없기 때문입니다. 검증 API 를 호출할 때마다 이 시각은 뒤로 밀립니다 — DNS 전파를 기다리는 동안 계속 호출하고 있다면 회수되지 않습니다. `status` 가 `verified` 나 `failed` 면 회수 대상이 아니므로 `null` 입니다.
- `createdAt` (datetime, optional)
- `updatedAt` (datetime, optional)

## Errors

### 401 Unauthorized Error

인증 실패

- `error` (string, optional) — 사람이 읽을 수 있는 에러 메시지
- `code` (string, optional) — 기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서 바뀔 수 있지만 코드는 계약입니다. 같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는 - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서 해제해야 발신됩니다. - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다. 전화번호 정규화 관련: - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님) - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)
- `ip` (string, optional) — `overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다. 해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔 「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.

### 403 Forbidden Error

접근 권한 없음

- `error` (string, optional) — 사람이 읽을 수 있는 에러 메시지
- `code` (string, optional) — 기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서 바뀔 수 있지만 코드는 계약입니다. 같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는 - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서 해제해야 발신됩니다. - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다. 전화번호 정규화 관련: - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님) - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)
- `ip` (string, optional) — `overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다. 해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔 「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.

### 404 Not Found Error

도메인을 찾을 수 없음 (email_domain_not_found)

- `error` (string, optional) — 사람이 읽을 수 있는 에러 메시지
- `code` (string, optional) — 기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서 바뀔 수 있지만 코드는 계약입니다. 같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는 - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서 해제해야 발신됩니다. - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다. 전화번호 정규화 관련: - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님) - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)
- `ip` (string, optional) — `overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다. 해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔 「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.

### 422 Unprocessable Entity Error

수신이 꺼져 있음 (email_domain_receiving_disabled)

- `error` (string, optional) — 사람이 읽을 수 있는 에러 메시지
- `code` (string, optional) — 기계 판독용 에러 코드. **분기는 이 값으로 하세요** — `error` 문구는 안내를 다듬으면서 바뀔 수 있지만 코드는 계약입니다. 같은 상태 코드라도 대응이 갈리는 경우가 있습니다. 예를 들어 발신의 `422` 는 - `recipient_blocked`: 수신거부 명단에 있는 번호입니다. 재시도하지 말고 명단에서 해제해야 발신됩니다. - `quota_exceeded`: 플랜 한도를 넘었습니다. 다음 주기에 다시 발신됩니다. 전화번호 정규화 관련: - `INVALID_PHONE_NUMBER`: 전화번호 포맷 오류 (한국 번호 형식 아님) - `UNSUPPORTED_COUNTRY`: 국제 발신 미지원 (+82 외 국가코드)
- `ip` (string, optional) — `overseas_ip_blocked` 일 때만 옵니다. 국외 IP 라고 판정한 요청 IP 입니다. 해외 리전 클라우드 서버에서 호출한다면 이 값이 그 서버의 공인 IP 이며, 콘솔 「국외 접속 예외」에서 예외를 신청할 때 이 고정 IP 를 적습니다.

## Types

### EmailDomainDnsRecord

고객이 자기 DNS 에 심어야 하는 레코드. 공급자 중립 형식이라 ClawOps 가 나중에 다른 이메일 공급자를 쓰더라도 이 모양은 그대로입니다.

- `purpose` (enum, optional) — 이 레코드가 무엇을 위한 것인지. \| 값 | 뜻 | | --- | --- | | `dkim` | 발신 서명 검증(CNAME 3건) | | `mail_from_mx` | 반송 주소를 내 도메인으로 옮기기 위한 MX 1건 | | `mail_from_spf` | 그 반송 주소의 SPF TXT 1건 | | `dmarc` | 도메인 인증 정책 TXT 1건 — **이미 심어 두셨다면 안내되지 않습니다** | | `inbound` | 이 도메인으로 **메일을 받기 위한** MX 1건 | ⚠️ `inbound` 레코드는 **수신을 켠 도메인에만** 포함됩니다. 수신을 쓰지 않는데 MX 를 심으면 그 도메인으로 오는 모든 메일이 ClawOps 로 향한 뒤 버려집니다. ⛔ `mail_from_*` 두 건은 **`bounce.<도메인>` 이라는 전용 이름**에 심습니다. 그 이름은 다른 용도로 쓰면 안 되고, **MX 가 정확히 하나**여야 합니다(둘 이상이면 반송 주소 설정이 실패합니다). ⚠️ 값은 늘어날 수 있습니다. **모르는 값을 만나면 `requirement` 를 보고 판단**하십시오.
  - Allowed values: `dkim`, `mail_from_mx`, `mail_from_spf`, `dmarc`, `inbound`
- `requirement` (enum, optional) — 이 레코드를 **안 심으면 무슨 일이 일어나는지**. 목록을 나눌 때는 `purpose` 가 아니라 이 값을 쓰십시오 — `purpose` 는 앞으로 늘어나지만 이 세 값은 늘어나지 않습니다. - `required` — 심지 않으면 **발송 자체가 열리지 않습니다.** - `recommended` — 없어도 발송은 됩니다. **도달률만 떨어집니다**(인증 실패·스팸 판정). - `optional` — 그 기능을 쓸 때만 필요합니다. 쓰지 않는다면 **심지 마십시오.**
  - Allowed values: `required`, `recommended`, `optional`
- `type` (enum, optional) — DNS 레코드 타입. ⚠️ `TXT` 값에는 **따옴표가 들어 있지 않습니다.** DNS 서비스 대부분이 입력한 값을 알아서 따옴표로 감싸므로, 따옴표를 직접 붙이면 이중이 되어 조용히 무효가 됩니다. 따옴표를 요구하는 서비스라면 그 화면의 안내를 따르십시오.
  - Allowed values: `CNAME`, `MX`, `TXT`
- `name` (string, optional) — 레코드 이름(호스트). DNS 공급자에 따라 도메인 부분을 빼고 앞부분만 입력해야 할 수 있습니다.
- `value` (string, optional) — 레코드 값(대상).
- `priority` (integer, optional, nullable) — MX 우선순위. `CNAME` 에서는 항상 `null` 이고, `MX` 에서는 항상 값이 있습니다. ⚠️ **이 값이 그 도메인 MX 중 단독으로 가장 낮아야 합니다.** 더 낮거나 **같은** 값의 다른 MX 가 있으면 메일이 그쪽으로 가거나 둘로 나뉩니다.

## Examples

**Response**

```json
{
  "id": "clx9edm00001",
  "domain": "mail.example.com",
  "status": "pending",
  "dnsRecords": [
    {
      "purpose": "dkim",
      "requirement": "required",
      "type": "CNAME",
      "name": "abc123._domainkey.mail.example.com",
      "value": "abc123.dkim.amazonses.com",
      "priority": null
    }
  ],
  "receivingEnabled": false,
  "receivingStatus": null,
  "receivingCheckedAt": null,
  "mailFromStatus": null,
  "dmarcStatus": null,
  "lastCheckedAt": "2026-09-02T00:00:00.000Z",
  "verifiedAt": null,
  "pendingExpiresAt": "2026-09-05T00:00:00.000Z",
  "createdAt": "2026-09-02T00:00:00.000Z",
  "updatedAt": "2026-09-02T00:00:00.000Z"
}
```

**SDK Code**

```python
import requests

url = "https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification"

headers = {"Authorization": "Bearer <token>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification';
const options = {method: 'POST', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.claw-ops.com/v1/accounts/AC1a2b3c4d/email-domains/clx9edm00001/receiving-verification")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```