---
title: "Transfer domain from another provider"
method: POST
path: "/api/domains/transfer"
tags: ["Domains"]
---

# Transfer domain from another provider

`POST /api/domains/transfer`

## Request

- Base URL: `https://domani.run`
- URL: `https://domani.run/api/domains/transfer`
- Auth: HTTP bearer

Initiate a domain transfer-in after planDomainAdoption and explicit price confirmation. Requires the authorization/EPP code from the current provider. The existing authoritative nameservers are preserved and verified. DNS migration is never implicit. Transfer typically takes 1-5 days to complete. Payment is charged upfront via card or USDC.

## Request body

- object
  - `domain` string, required: Domain to transfer, e.g. mysite.com
  - `auth_code` string, required: Authorization/EPP code from the current provider
  - `payment_method` 'card' | 'usdc' | 'balance': Payment method: 'card' (default), 'usdc', or 'balance' (marketplace credit).
  - `payment_tx` string: Transaction hash of a USDC payment already sent on-chain.
  - `payment_chain` 'base' | 'ethereum': Chain the USDC payment was sent on.
  - `extra_subdomains` string[]: Additional subdomains to include in the pre-transfer DNS snapshot. We auto-discover subdomains via CT logs, SPF, MX/DKIM inference, and a common wordlist - use this for any custom subdomains we might miss.
  - `max_price` number: Ceiling in USD for the transfer charge. If the real price exceeds it, the request fails with 400 PRICE_ABOVE_MAX and nothing is charged. Without max_price, the ceiling is the listed transfer price: when only a dearer registrar can take it, the transfer fails the same way. The error's `price` field is the total to accept; confirm it with the user before retrying with that max_price.

## Response `202`

Transfer initiated

- object
  - `domain` string, required
  - `status` 'pending' | 'active', required
  - `expires` string, date-time, required
  - `price` number, required
  - `currency` string, required
  - `payment_method` string, required
  - `payment_tx` string
  - `auto_renew` boolean
  - `hint` string, required
  - `dns_snapshot` object: Recovery backup summary captured before transfer. It is not applied unless an explicit recovery operation is needed.
    - `record_count` integer: Total DNS records captured
    - `subdomain_count` integer: Number of subdomains discovered
  - `nameservers_preserved` true, required
  - `dns_migration` 'not_requested', required
  - `continuity` object, required
    - `nameservers` string[]
    - `dns_provider` string
    - `dnssec_enabled` boolean
    - `verification_status` 'verified' | 'repaired' | 'degraded' | 'unknown'

## Other responses

- `400`: Invalid request parameters, or PRICE_ABOVE_MAX: the transfer costs more than max_price, or (without max_price) more than the listed transfer price, because the registrar with the listed price cannot take it right now. Nothing was charged; show `price` to the user and retry with max_price of at least `price` to accept.
- `401`: Missing or invalid API key
- `402`: Payment required
- `409`: Domain already registered in our system
- `429`: Rate limit exceeded - wait and retry
- `503`: REGISTRAR_CREDIT: no registrar that sells the name has the prepaid credit for this transfer right now and none could be topped up. Nothing was charged; retry later.

---

[API](https://skmtc.dev/domani/apis/domani-run-api.md) · [All operations](https://skmtc.dev/domani/apis/domani-run-api/llms.txt) · [OpenAPI document](https://skmtc.dev/domani/apis/domani-run-api/revisions/7679f8159533?raw)
