# DNSHE 도메인 API 참조 문서
English · 简体中文 · 繁體中文 · 日本語 · Русский · Bahasa Indonesia · Deutsch · Français · 한국어 · العربية
[서비스 소개로 돌아가기](../README_KO.md) 도메인 등록, DNS 관리, 동적 IP 갱신 및 계정 작업을 자동화합니다. 예시는 DNSHE API 주소와 임시 인증 정보를 사용합니다. 이름, ID, 키는 자신의 리소스로 바꿔 주세요. ## 목차 - [시작하기](#시작하기) - [인증 및 요청 규칙](#인증-및-요청-규칙) - [도메인 관리](#도메인-관리) - [DNS 레코드 관리](#dns-레코드-관리) - [동적 DNS (DDNS)](#동적-dns-ddns) - [API 키 관리](#api-키-관리) - [도메인 양도](#도메인-양도) - [할당량](#할당량) - [WHOIS 조회](#whois-조회) - [오류 및 요청 제한](#오류-및-요청-제한) - [클라이언트 예제](#클라이언트-예제) - [보안 및 자주 묻는 질문](#보안-및-자주-묻는-질문) - [지원](#지원) ## 시작하기 ```text https://api005.dnshe.com/index.php?m=domain_hub ``` 기본 URL에 이미 `m=domain_hub`가 있으므로 추가 매개변수는 `&`로 연결합니다. GET 쿼리 매개변수 외에는 JSON을 사용합니다. 일반 인증 요청은 기본 분당 60회이며 운영자가 조정할 수 있습니다. 기능은 계정과 배포 설정에 따라 달라집니다. 셸 예시는 Bash/sh용이며 먼저 아래 환경 변수를 설정하세요. ```bash export DNSHE_API_KEY='replace-with-your-api-key' export DNSHE_API_SECRET='replace-with-your-api-secret' export DNSHE_DDNS_TOKEN='replace-with-your-ddns-token' ``` ## 인증 및 요청 규칙 고객 영역 → [도메인 관리](https://my.dnshe.com/index.php?m=domain_hub) → API 관리에서 첫 키를 생성합니다. `X-API-Key`와 `X-API-Secret` 헤더로 인증하며 URL이나 본문으로 인증 정보를 보내는 방식은 비활성화되어 있습니다. GET은 쿼리 문자열, 쓰기 요청은 `Content-Type: application/json`과 JSON 본문을 사용합니다. `endpoint`는 리소스, `action`은 작업입니다. `quota`, `whois`에는 `action`이 필요 없습니다. DDNS는 별도 토큰을 사용합니다. ## 도메인 관리 ### 1.1 도메인 목록 `GET` · `endpoint=subdomains` · `action=list` #### 매개변수 - `page` — `integer`; 선택; 기본값 / 범위: `1`. - `cursor_id` — `integer`; 선택. - `per_page` — `integer`; 선택; 기본값 / 범위: `200; 1–500`. - `include_total` — `boolean`; 선택; 기본값 / 범위: `false`. - `search` — `string`; 선택. - `rootdomain` — `string`; 선택. - `status` — `string`; 선택; 기본값 / 범위: `active | suspended | expired`. - `created_from / created_to` — `string`; 선택; 기본값 / 범위: `YYYY-MM-DD`. - `sort_by` — `string`; 선택; 기본값 / 범위: `id`. - `sort_dir` — `string`; 선택; 기본값 / 범위: `desc; asc | desc`. - `fields` — `string`; 선택; 기본값 / 범위: `all`. `page`는 1부터 시작하는 호환 페이지 번호입니다. 대규모 목록은 `cursor_id=0`으로 시작하고 `pagination.has_more=true`인 동안 `pagination.next_cursor_id`를 다음 커서로 사용하며 false에서 종료합니다. 커서 모드는 OFFSET 없이 ID 순서를 사용합니다. `per_page`는 기본 200, 최대 500이며 50–100부터 권장합니다. `include_total=1`은 비용이 큰 전체 개수 조회를 추가합니다. `search`는 접두사 또는 루트 도메인을 검색하며 `rootdomain`, `status`, `created_from`, `created_to`는 필터입니다. 날짜는 YYYY-MM-DD입니다. `sort_by`: `id`, `created_at`, `updated_at`, `expires_at`, `subdomain`; `sort_dir`: `asc` 또는 `desc`. `fields`는 쉼표로 구분하거나 `all`을 사용합니다: `id`, `subdomain`, `rootdomain`, `full_domain`, `status`, `created_at`, `updated_at`, `expires_at`, `never_expires`, `cloudflare_zone_id`, `provider_account_id`. 선택 시에도 `id`는 포함됩니다. `count`는 반환된 목록의 개수이며 전체 일치 결과 수를 의미하지 않을 수 있습니다. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X GET "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=list" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" ``` ```bash curl --fail-with-body --silent --show-error --max-time 30 -X GET "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=list&cursor_id=0&per_page=100&fields=id,subdomain,rootdomain,status" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" ``` ```bash curl --fail-with-body --silent --show-error --max-time 30 -X GET "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=list&search=test&rootdomain=de5.net&status=active&sort_by=expires_at&sort_dir=asc&per_page=50" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" ``` #### 응답 예시 ```json { "success": true, "count": 2, "subdomains": [ { "id": 1, "subdomain": "test", "rootdomain": "de5.net", "full_domain": "test.de5.net", "status": "active", "created_at": "2025-10-19 10:00:00", "updated_at": "2025-10-19 10:00:00" }, { "id": 2, "subdomain": "api", "rootdomain": "de5.net", "full_domain": "api.de5.net", "status": "active", "created_at": "2025-10-19 11:00:00", "updated_at": "2025-10-19 11:00:00" } ] } ``` ```json { "success": true, "count": 1, "subdomains": [ { "id": 901, "subdomain": "test", "rootdomain": "de5.net", "full_domain": "test.de5.net", "status": "active" } ], "pagination": { "mode": "cursor", "page": 1, "per_page": 100, "has_more": true, "cursor_id": 0, "next_cursor_id": 901 } } ``` ### 1.2 도메인 등록 `POST` · `endpoint=subdomains` · `action=create` #### 매개변수 - `subdomain` — `string`; 필수. - `domain` — `string`; 필수. `subdomain`은 `myapp` 같은 접두사이고 `domain`은 `de5.net` 같은 사용 가능한 루트 도메인입니다. 등록은 `action=create` 및 `domain` 필드를 사용합니다. 응답과 목록 필터의 `rootdomain`은 등록 필드가 아닙니다. 사용 가능 여부와 계정 한도가 적용됩니다. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=create" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "subdomain": "myapp", "domain": "de5.net" }' ``` #### 응답 예시 ```json { "success": true, "message": "Subdomain registered successfully", "subdomain_id": 3, "full_domain": "myapp.de5.net" } ``` ### 1.3 도메인 상세 `GET` · `endpoint=subdomains` · `action=get` #### 매개변수 - `subdomain_id` — `integer`; 필수. 인증 계정이 소유한 도메인 ID를 지정합니다. 도메인 객체, `dns_records`, `dns_count`가 반환됩니다. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X GET "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=get&subdomain_id=1" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" ``` #### 응답 예시 ```json { "success": true, "subdomain": { "id": 1, "subdomain": "test", "rootdomain": "de5.net", "full_domain": "test.de5.net", "status": "active", "created_at": "2025-10-19 10:00:00", "updated_at": "2025-10-19 10:00:00" }, "dns_records": [ { "id": 1, "name": "test.de5.net", "type": "A", "content": "203.0.113.10", "ttl": 600, "priority": null, "status": "active", "created_at": "2025-10-19 10:05:00" } ], "dns_count": 1 } ``` ### 1.4 도메인 삭제 `POST / DELETE` · `endpoint=subdomains` · `action=delete` #### 매개변수 - `subdomain_id` — `integer`; 필수. 소유 도메인과 연결된 DNS 레코드를 삭제합니다. `dns_records_deleted`가 삭제 개수를 나타냅니다. 요청 전 대상 ID를 확인하세요. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=delete" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "subdomain_id": 1 }' ``` #### 응답 예시 ```json { "success": true, "message": "Subdomain deleted successfully", "subdomain_id": 1, "full_domain": "test.de5.net", "dns_records_deleted": 4 } ``` ### 1.5 도메인 갱신 `POST / PUT` · `endpoint=subdomains` · `action=renew` #### 매개변수 - `subdomain_id` — `integer`; 필수. DNSHE의 일반 무료 갱신은 무료이며 예시는 `charged_amount=0`입니다. 범용 플러그인은 유료 복구를 설정할 수 있으므로 복구 기간에는 상태와 콘솔 정책을 확인하세요. `previous_expires_at`, `new_expires_at`, `never_expires`, `remaining_days`, `charged_amount`로 실제 결과를 판단합니다. 갱신 오류: HTTP 403 `renewal disabled`, `redemption period requires administrator`, `renewal window expired`; HTTP 422 `renewal_not_yet_available`; HTTP 402 `insufficient balance for redemption renewal`; 없거나 다른 계정 소유인 도메인은 HTTP 404입니다. 갱신 기간을 확인하거나 지원에 문의하고 반복 호출하지 마세요. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=subdomains&action=renew" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "subdomain_id": 3 }' ``` #### 응답 예시 ```json { "success": true, "message": "Subdomain renewed successfully", "subdomain_id": 3, "subdomain": "myapp", "previous_expires_at": "2027-05-01 00:00:00", "new_expires_at": "2028-05-01 00:00:00", "renewed_at": "2027-04-30 00:00:00", "never_expires": 0, "status": "active", "remaining_days": 367, "charged_amount": 0 } ``` ## DNS 레코드 관리 ### 2.1 DNS 레코드 목록 `GET` · `endpoint=dns_records` · `action=list` #### 매개변수 - `subdomain_id` — `integer`; 필수. 목록/생성에서 반환된 모듈 `id`를 우선 사용하세요. 새 공개 레코드 ID는 15자리입니다. `record_id`는 DNS 제공업체 식별자입니다. 수정/삭제에는 최소 하나가 필요하며 둘 다 지정하면 같은 레코드여야 합니다. 불일치는 `dns_record_identifier_mismatch`입니다. 기존 내부 ID는 호환되며 숫자 `record_id`는 최소 2027-06-12까지 호환된다고 명시되어 있습니다. 새 구현은 모듈 ID를 `id`에 넣으세요. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X GET "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=dns_records&action=list&subdomain_id=1" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" ``` #### 응답 예시 ```json { "success": true, "count": 2, "records": [ { "id": 1, "record_id": "5a0ce6c4d1d4c71bc5e60a2a2a0e4997", "name": "test.de5.net", "type": "A", "content": "203.0.113.10", "ttl": 600, "priority": null, "line": null, "proxied": false, "status": "active", "created_at": "2025-10-19 10:05:00", "updated_at": "2025-10-19 10:05:00" }, { "id": 2, "name": "www.test.de5.net", "type": "CNAME", "content": "test.de5.net", "ttl": 600, "priority": null, "proxied": false, "status": "active", "created_at": "2025-10-19 10:10:00" } ] } ``` ### 2.2 DNS 레코드 생성 `POST` · `endpoint=dns_records` · `action=create` #### 매개변수 - `subdomain_id` — `integer`; 필수. - `type` — `string`; 필수. - `name` — `string`; 선택; 기본값 / 범위: `@`. - `content` — `string`; 선택. - `ttl` — `integer`; 선택; 기본값 / 범위: `600`. - `priority` — `integer`; 선택; 기본값 / 범위: `MX: 10; SRV: 0`. - `line` — `string`; 선택. - `record_weight / weight` — `integer`; 선택. - `record_port / port` — `integer`; 선택; 기본값 / 범위: `1–65535`. - `record_target / target` — `string`; 선택. - `caa_flag` — `integer`; 선택; 기본값 / 범위: `0; 0–255`. - `caa_tag` — `string`; 선택; 기본값 / 범위: `issue; 1–15 [A-Za-z0-9]`. - `caa_value` — `string`; 선택. `type`은 A, AAAA, CNAME, MX, TXT, NS, SRV, CAA를 지원합니다. `name`은 등록 도메인의 상대 이름이며 생략, 빈 값, `@`는 도메인 자체입니다. 전체 도메인 이름은 허용되지 않으며 `*`는 가장 왼쪽 레이블에만 가능합니다. `content`는 SRV/CAA 구조화 입력으로 생성하는 경우 외에는 필수입니다. `ttl` 기본 600초, `priority`는 MX 기본 10, SRV 기본 0입니다. SRV는 `record_weight`/`weight`, `record_port`/`port` (1–65535), `record_target`/`target`을 사용합니다. 대상 `.`는 서비스 이용 불가입니다. CAA는 `caa_flag` (0–255, 기본 0), `caa_tag` (영숫자 1–15자, 기본 `issue`), `caa_value`를 사용합니다. `line`은 AliDNS 전용이며 다른 제공업체는 비어 있지 않은 값을 거부합니다. `disable_ns_management`로 NS 쓰기가 비활성화될 수 있습니다. 외부 DNS 위임 후 비 NS 레코드 생성/수정은 `external_dns_delegated`로 거부됩니다. 기존 레코드 삭제, 정합성 처리, 만료 정리는 제한되지 않습니다. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=dns_records&action=create" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "subdomain_id": 1, "type": "A", "content": "203.0.113.10", "ttl": 600 }' ``` #### 응답 예시 ```json { "success": true, "message": "DNS record created successfully", "id": 738492016583241, "record_id": "5a0ce6c4d1d4c71bc5e60a2a2a0e4997" } ``` ### 2.3 DNS 레코드 수정 `POST / PUT / PATCH` · `endpoint=dns_records` · `action=modify` #### 매개변수 - `id` — `integer`; 선택. - `record_id` — `string`; 선택. - `type / name / content` — `string`; 선택. - `ttl / priority` — `integer`; 선택. - `line` — `string`; 선택. - `record_weight / weight` — `integer`; 선택. - `record_port / port` — `integer`; 선택. - `record_target / target` — `string`; 선택. - `caa_flag` — `integer`; 선택. - `caa_tag / caa_value` — `string`; 선택. `id` 또는 `record_id`와 변경할 필드를 보냅니다. 이름과 SRV/CAA 규칙은 생성과 같습니다. 두 식별자는 같은 레코드를 가리켜야 하며 응답에는 모듈 및 제공업체 ID가 반환됩니다. 목록/생성에서 반환된 모듈 `id`를 우선 사용하세요. 새 공개 레코드 ID는 15자리입니다. `record_id`는 DNS 제공업체 식별자입니다. 수정/삭제에는 최소 하나가 필요하며 둘 다 지정하면 같은 레코드여야 합니다. 불일치는 `dns_record_identifier_mismatch`입니다. 기존 내부 ID는 호환되며 숫자 `record_id`는 최소 2027-06-12까지 호환된다고 명시되어 있습니다. 새 구현은 모듈 ID를 `id`에 넣으세요. `disable_ns_management`로 NS 쓰기가 비활성화될 수 있습니다. 외부 DNS 위임 후 비 NS 레코드 생성/수정은 `external_dns_delegated`로 거부됩니다. 기존 레코드 삭제, 정합성 처리, 만료 정리는 제한되지 않습니다. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=dns_records&action=modify" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "id": 738492016583241, "type": "A", "content": "203.0.113.20", "ttl": 600 }' ``` #### 응답 예시 ```json { "success": true, "message": "DNS record updated successfully", "id": 738492016583241, "record_id": "5a0ce6c4d1d4c71bc5e60a2a2a0e4997" } ``` ### 2.4 DNS 레코드 삭제 `POST / DELETE` · `endpoint=dns_records` · `action=delete` #### 매개변수 - `id` — `integer`; 선택. - `record_id` — `string`; 선택. 목록/생성에서 반환된 모듈 `id`를 우선 사용하세요. 새 공개 레코드 ID는 15자리입니다. `record_id`는 DNS 제공업체 식별자입니다. 수정/삭제에는 최소 하나가 필요하며 둘 다 지정하면 같은 레코드여야 합니다. 불일치는 `dns_record_identifier_mismatch`입니다. 기존 내부 ID는 호환되며 숫자 `record_id`는 최소 2027-06-12까지 호환된다고 명시되어 있습니다. 새 구현은 모듈 ID를 `id`에 넣으세요. #### 요청 예시 ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=dns_records&action=delete" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "id": 1 }' ``` ```bash curl --fail-with-body --silent --show-error --max-time 30 -X POST "https://api005.dnshe.com/index.php?m=domain_hub&endpoint=dns_records&action=delete" \ -H "X-API-Key: ${DNSHE_API_KEY}" \ -H "X-API-Secret: ${DNSHE_API_SECRET}" \ -H "Content-Type: application/json" \ -d '{ "record_id": "5a0ce6c4d1d4c71bc5e60a2a2a0e4997" }' ``` #### 응답 예시 ```json { "success": true, "message": "DNS record deleted successfully" } ``` ## 동적 DNS (DDNS) `GET / POST / PUT` · `endpoint=ddns` · `action=update` 도메인 관리 → DDNS에서 특정 A/AAAA 레코드용 토큰을 생성합니다. `Authorization: Bearer