Skip to content

Claim a domain

Take over a domain another team has already verified, by proving you own it.

http
POST /v1/domains/claim

Requires a Full access API key.

Use this only when a domain is already verified by a different team and you control the DNS for it. If no other team has it, add it the normal way with Create a domain instead.

Body parameters

ParameterTypeRequiredDescription
namestringYesThe domain to claim, e.g. example.com. A valid, lowercase domain; max 253 characters.
regionstringNoWhere your sending identity will live once the claim verifies: us-east-1, eu-west-1, sa-east-1 or ap-northeast-1. Defaults to us-east-1.
custom_return_pathstringNoThe Return-Path subdomain for your identity. A bare label; max 63 characters. Defaults to send.

Example

bash
curl -X POST 'https://api.sendgrail.com/v1/domains/claim' \
  -H "Authorization: Bearer $SENDGRAIL_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "example.com",
    "region": "us-east-1",
    "custom_return_path": "send"
  }'
js
const res = await fetch('https://api.sendgrail.com/v1/domains/claim', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SENDGRAIL_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'example.com',
    region: 'us-east-1',
    custom_return_path: 'send',
  }),
});

const claim = await res.json();

Response

201 Created. A placeholder domain is created on your team, plus a domain_claim carrying the TXT record you must publish to prove ownership.

json
{
  "object": "domain_claim",
  "id": "9a3c1e64-1b17-4f8c-9f0e-3b6c1e0f5c31",
  "name": "example.com",
  "status": "pending",
  "domain_id": "5f1c3a9e-0d42-4b7c-9a63-2e8b41d7c015",
  "region": "us-east-1",
  "record": {
    "type": "TXT",
    "name": "example.com",
    "value": "sendgrail-domain-verification=6f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c",
    "ttl": "Auto"
  },
  "blocked_reason": null,
  "failure_reason": null,
  "created_at": "2026-07-14T19:44:32+00:00",
  "expires_at": "2026-07-21T19:44:32+00:00"
}
FieldDescription
objectAlways domain_claim.
idThe claim id.
nameThe domain being claimed.
statuspending, verified or failed.
domain_idThe placeholder domain's id. This is the id you poll and verify with — see below.
regionWhere your identity will live once verified.
recordThe ownership TXT record to publish: type, name, value and ttl.
blocked_reasonWhy the claim can't proceed, or null.
failure_reasonWhy the last verification attempt failed, or null.
created_atISO 8601 time the claim was opened.
expires_atISO 8601 time the claim expires — 7 days out. After this it can no longer be verified.

The claim flow

  1. Open the claim with this call. Note domain_id — the placeholder domain's id, which every later step uses.
  2. Publish the TXT record from record at your DNS provider.
  3. Verify with Verify a domain claim, or poll it with Get a domain claim.
  4. On success the placeholder becomes your own sending identity, with its own DKIM. Retrieve the domain to get its new records, add them, and run Verify a domain to finish standing it up.

You have 7 days — after expires_at, the claim goes failed and you must start over.

You already own it — 409

If the domain is already on your team, there's nothing to claim:

json
{
  "message": "This domain is already on your team — no claim needed.",
  "code": "domain_exists",
  "request_id": "8f2c1e64-1b17-4f8c-9f0e-3b6c1e0f5c31"
}

Nothing to claim — 422

Claiming only makes sense when another team has verified the domain. If no one has, add it directly instead:

json
{
  "message": "No other team has verified this domain. Add it with POST /v1/domains instead.",
  "code": "nothing_to_claim",
  "request_id": "8f2c1e64-1b17-4f8c-9f0e-3b6c1e0f5c31"
}

A Sending access key answers 403. See Errors.

Transactional email on your own domain.