TransferPrecheckResponse
The public precheck payload. The frontend checker is built against it. **Additive only.** Every key below `source` was added after the page shipped, and nothing above it may be removed or renamed: the checker reads the payload as a typed object, and a renamed key is a blank on a public page. `tests/test_transfer_precheck_parity.py` pins the original key set. The last four fields are the ones the MCP tool `check_domain_transfer` has always carried. They come from the same builder (`shared/services/transfer_handoff`), so an agent with no MCP client gets the same `ready`, the same handoff link, the same next step and - the one that matters - the same authorization-code refusal, byte for byte. The one key that still differs is the projected date: `new_expiry` here, `expected_new_expiry` on the tool.
Properties
| Name | Type | Description |
|---|---|---|
| domain | string | |
| tld | string | |
| supported | boolean | |
| checked_at | string | |
| blockers | array | |
| registrar | object | |
| nameservers | array | |
| dns_continuity | object | |
| price | object | |
| source | object | |
| ready | boolean | TRUE only when `blockers` is empty. A convenience over that list that can never disagree with it: anything we could not establish becomes a blocker, so a registry timeout reads as not ready. |
| transfer_url | string | The page on justdomain.ai a PERSON opens in a browser to take this further. |
| next_step | string | One sentence about what happens next, already matched to this domain's state. Written to be relayed to a person as-is. |
| auth_code_policy | string | Constant. The rule about authorization (EPP) codes, restated in every payload so it travels with the answer. |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/justdomain-ai/json-schema/justdomain-ai-transfer-precheck-response-schema.json",
"title": "TransferPrecheckResponse",
"description": "The public precheck payload. The frontend checker is built against it.\n\n**Additive only.** Every key below `source` was added after the page\nshipped, and nothing above it may be removed or renamed: the checker\nreads the payload as a typed object, and a renamed key is a blank on a\npublic page. `tests/test_transfer_precheck_parity.py` pins the original\nkey set.\n\nThe last four fields are the ones the MCP tool `check_domain_transfer`\nhas always carried. They come from the same builder\n(`shared/services/transfer_handoff`), so an agent with no MCP client gets\nthe same `ready`, the same handoff link, the same next step and - the\none that matters - the same authorization-code refusal, byte for byte.\nThe one key that still differs is the projected date: `new_expiry` here,\n`expected_new_expiry` on the tool.",
"x-generated": "2026-11-13",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/mcp-openapi.json#/components/schemas/TransferPrecheckResponse",
"properties": {
"domain": {
"type": "string",
"title": "Domain"
},
"tld": {
"type": "string",
"title": "Tld"
},
"supported": {
"type": "boolean",
"title": "Supported"
},
"checked_at": {
"type": "string",
"title": "Checked At"
},
"blockers": {
"items": {
"$ref": "#/$defs/TransferBlockerOut"
},
"type": "array",
"title": "Blockers",
"default": []
},
"registrar": {
"$ref": "#/$defs/TransferRegistrarOut"
},
"nameservers": {
"items": {
"type": "string"
},
"type": "array",
"title": "Nameservers",
"default": []
},
"dns_continuity": {
"$ref": "#/$defs/DnsContinuityOut"
},
"price": {
"anyOf": [
{
"$ref": "#/$defs/TransferPriceOut"
},
{
"type": "null"
}
]
},
"source": {
"$ref": "#/$defs/TransferPrecheckSourceOut"
},
"ready": {
"type": "boolean",
"title": "Ready",
"description": "TRUE only when `blockers` is empty. A convenience over that list that can never disagree with it: anything we could not establish becomes a blocker, so a registry timeout reads as not ready."
},
"transfer_url": {
"type": "string",
"title": "Transfer Url",
"description": "The page on justdomain.ai a PERSON opens in a browser to take this further."
},
"next_step": {
"type": "string",
"title": "Next Step",
"description": "One sentence about what happens next, already matched to this domain's state. Written to be relayed to a person as-is."
},
"auth_code_policy": {
"type": "string",
"title": "Auth Code Policy",
"description": "Constant. The rule about authorization (EPP) codes, restated in every payload so it travels with the answer."
}
},
"type": "object",
"required": [
"domain",
"tld",
"supported",
"checked_at",
"registrar",
"dns_continuity",
"source",
"ready",
"transfer_url",
"next_step",
"auth_code_policy"
],
"$defs": {
"DnsContinuityOut": {
"properties": {
"case": {
"type": "string",
"title": "Case"
},
"provider": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Provider"
},
"detail": {
"type": "string",
"title": "Detail"
},
"records": {
"items": {
"$ref": "#/$defs/DnsRecordOut"
},
"type": "array",
"title": "Records",
"default": []
},
"records_probed": {
"type": "boolean",
"title": "Records Probed",
"default": false
},
"records_unreadable": {
"type": "integer",
"title": "Records Unreadable",
"default": 0
},
"records_notes": {
"items": {
"type": "string"
},
"type": "array",
"title": "Records Notes",
"default": []
}
},
"type": "object",
"required": [
"case",
"detail"
],
"title": "DnsContinuityOut",
"description": "Does DNS keep working after the transfer?\n\n\"independent\" - the nameservers belong to a DNS provider, not to the\nlosing registrar, so a transfer does not touch them. \"losing_registrar\" -\nthe dangerous case: the old registrar eventually stops serving the zone.\n\"unknown\" - we do not recognise the nameservers, said plainly.\n\n`records` is the public-DNS probe the wizard renders for its \"does this\nlook complete?\" review. It is only populated when the caller asks for it\n(`include_records`), because the probe is ~57 lookups against public\nresolvers and the checker page does not need them to answer its own\nquestion. **`records_probed` is how a client tells \"we did not look\" from\n\"there is nothing there\"** - an empty `records` with `records_probed:\nfalse` means the first, and treating it as the second is how somebody\nstages an empty zone."
},
"DnsRecordOut": {
"properties": {
"type": {
"type": "string",
"title": "Type",
"description": "A, AAAA, CNAME, MX, TXT, NS, SRV, CAA."
},
"name": {
"type": "string",
"title": "Name",
"description": "The absolute host, e.g. 'example.com' or '_dmarc.example.com'."
},
"value": {
"type": "string",
"title": "Value"
},
"ttl": {
"type": "integer",
"title": "Ttl",
"default": 3600
},
"prio": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Prio"
}
},
"type": "object",
"required": [
"type",
"name",
"value"
],
"title": "DnsRecordOut",
"description": "One DNS record, in the five fields the rest of the product uses.\n\nIdentical in shape to what the DNS-management screen sends, so a record\nread off somebody else's nameservers and a record typed into our own\nform are the same object and never need translating between the two."
},
"TransferBlockerOut": {
"properties": {
"code": {
"type": "string",
"title": "Code"
},
"detail": {
"type": "string",
"title": "Detail"
},
"eligible_at": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Eligible At"
}
},
"type": "object",
"required": [
"code",
"detail"
],
"title": "TransferBlockerOut"
},
"TransferPrecheckSourceOut": {
"properties": {
"rdap": {
"type": "boolean",
"title": "Rdap"
},
"registrar_pricing": {
"type": "boolean",
"title": "Registrar Pricing"
}
},
"type": "object",
"required": [
"rdap",
"registrar_pricing"
],
"title": "TransferPrecheckSourceOut",
"description": "Which sources actually answered on this request.\n\n`registrar_pricing: false` means the price is missing because we could\nnot read it, not because the domain is free to transfer."
},
"TransferPriceOut": {
"properties": {
"amount": {
"type": "string",
"title": "Amount"
},
"currency": {
"type": "string",
"title": "Currency"
},
"term_years": {
"type": "integer",
"title": "Term Years"
},
"term_note": {
"type": "string",
"title": "Term Note"
},
"new_expiry": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "New Expiry"
},
"is_premium": {
"type": "boolean",
"title": "Is Premium"
}
},
"type": "object",
"required": [
"amount",
"currency",
"term_years",
"term_note",
"is_premium"
],
"title": "TransferPriceOut"
},
"TransferRegistrarOut": {
"properties": {
"name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Name"
},
"iana_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Iana Id"
}
},
"type": "object",
"title": "TransferRegistrarOut",
"description": "Who sponsors the domain today, as the REGISTRY reports it."
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/justdomain-ai-transfer-precheck-response"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.