---
title: "Transfer a domain to Hypamoon"
method: POST
path: "/domains/transfer"
tags: ["Domains"]
---

# Transfer a domain to Hypamoon

`POST /domains/transfer`

## Request

- Base URL: `https://api.hypamoon.com/api/v1`
- URL: `https://api.hypamoon.com/api/v1/domains/transfer`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://app.hypamoon.com/oauth/authorize`, token URL `https://api.hypamoon.com/oauth/token`, scopes: `sites:write`)

Moves the registration of a domain the user owns to Hypamoon, with the transfer code of the current registrar. accept_registry_terms must be true and max_price_eur is the amount the user confirmed. dns hypamoon switches the nameservers to the zone here when the transfer completes, so it is refused with confirmation_required (nothing charged) while the preflight is not ready, unless ignore_preflight; keep leaves them as they are. Needs an Idempotency-Key; a key whose attempt failed is never retried. 201 when the transfer completes immediately, 202 while it is in progress (follow it with GET /domains/{id}). In live mode the price is deducted from the balance and refunded if the transfer fails. Transfers in live mode are not open yet: until they are, a live key gets service_unavailable, and test mode works as described.

## Headers

- `Idempotency-Key` string, required

## Request body

- DomainTransferInput
  - `domain` string, required: The domain to move to Hypamoon, like example.com.
  - `authcode` string: The transfer code (auth code, EPP code; for .nl the token) the user got from their current registrar. Required for most extensions. Never stored.
  - `accept_registry_terms` boolean, required: Must be true: the user (the registrant) explicitly accepted the terms of the registry at registry_terms_url from check_domain.
  - `max_price_eur` number, required: The highest amount the user agreed to pay for the transfer. Refused if the price is higher.
  - `dns` 'hypamoon' | 'keep': hypamoon (default): the nameservers switch to the DNS zone here when the transfer completes; run preflight_domain first. keep: the nameservers stay as they are; switch later with switch_domain_nameservers.
  - `site_id` string, uuid, nullable: Optional. A site of this project to serve on the domain once it is active.
  - `dkim_selectors` string[]: Optional. The DKIM selector(s) of the user's mail provider, so their DKIM records are copied too.
  - `ignore_preflight` boolean: Optional, default false. With dns hypamoon the nameservers switch when the transfer completes, so the transfer is refused (confirmation_required, nothing charged) while preflight_domain is not ready. true transfers anyway, only when the user accepts the listed differences.

## Response `201`

The transfer completed.

## Other responses

- `202`: The transfer was requested and is in progress; transfer.status shows where it stands.
- `400`: Bad Request: invalid_json, idempotency_key_missing, idempotency_key_invalid.
- `401`: Unauthorized: unauthorized, missing_api_key, invalid_api_key, api_key_revoked, project_deleted.
- `402`: Payment Required: payment_mandate_missing, billing_blocked, insufficient_balance.
- `403`: Forbidden: project_not_enabled, key_mode_mismatch, missing_scope, verification_required, forbidden.
- `404`: Not Found: not_found.
- `409`: Conflict: idempotency_key_reused, idempotency_request_in_progress, conflict, confirmation_required.
- `422`: Unprocessable Content: validation_failed, company_details_missing, spend_cap_missing.
- `429`: Too Many Requests: rate_limited.
- `500`: Internal Server Error: internal_error.
- `502`: Bad Gateway: upstream_error.
- `503`: Service Unavailable: service_unavailable.

---

[API](https://skmtc.dev/hypamoon/apis/hypamoon-api.md) · [All operations](https://skmtc.dev/hypamoon/apis/hypamoon-api/llms.txt) · [OpenAPI document](https://skmtc.dev/hypamoon/apis/hypamoon-api/revisions/9f0b90004c06?raw)
