BETA
Skip to content

Domains ​

Manage the sending domains used by your team. Emails can only be sent from addresses on a verified domain.

Base URL: https://app.krafter.dev/api/v1

Add Domain ​

Registers a new sending domain and returns the DNS records you must configure.

POST /domains

Required scope: domains:manage

Request Body ​

FieldTypeRequiredDescription
domainstringYesThe domain name (e.g. example.com).
return_pathstringNoSubdomain prefix used as the custom MAIL FROM (e.g. "send" produces send.example.com). Defaults to "send". Must start with a letter, contain only letters/digits/hyphens, and be at most 63 characters.

Example Request ​

bash
curl -X POST https://app.krafter.dev/api/v1/domains \
  -H "Authorization: Bearer kr_live_abc123def456" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com",
    "return_path": "send"
  }'

Example Response ​

json
// 201 Created
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "domain": "example.com",
    "status": "pending",
    "verified_at": null,
    "created_at": "2026-01-15T10:00:00Z",
    "dns_records": [
      {
        "type": "TXT",
        "name": "_amazonses.example.com",
        "value": "abc123...",
        "ttl": "Auto",
        "priority": null,
        "purpose": "Domain verification — proves you own this domain",
        "required": true,
        "category": "verification"
      },
      {
        "type": "CNAME",
        "name": "token1._domainkey.example.com",
        "value": "token1.dkim.amazonses.com",
        "ttl": "Auto",
        "priority": null,
        "purpose": "DKIM — cryptographic email signature",
        "required": true,
        "category": "delivery"
      },
      {
        "type": "CNAME",
        "name": "token2._domainkey.example.com",
        "value": "token2.dkim.amazonses.com",
        "ttl": "Auto",
        "priority": null,
        "purpose": "DKIM — cryptographic email signature",
        "required": true,
        "category": "delivery"
      },
      {
        "type": "CNAME",
        "name": "token3._domainkey.example.com",
        "value": "token3.dkim.amazonses.com",
        "ttl": "Auto",
        "priority": null,
        "purpose": "DKIM — cryptographic email signature",
        "required": true,
        "category": "delivery"
      },
      {
        "type": "MX",
        "name": "send.example.com",
        "value": "feedback-smtp.eu-central-1.amazonses.com",
        "ttl": "Auto",
        "priority": 10,
        "purpose": "Custom MAIL FROM — bounce handling",
        "required": true,
        "category": "delivery"
      },
      {
        "type": "TXT",
        "name": "send.example.com",
        "value": "v=spf1 include:amazonses.com ~all",
        "ttl": "Auto",
        "priority": null,
        "purpose": "SPF — authorizes SES to send on your behalf",
        "required": true,
        "category": "delivery"
      },
      {
        "type": "TXT",
        "name": "_dmarc.example.com",
        "value": "v=DMARC1; p=none;",
        "ttl": "Auto",
        "priority": null,
        "purpose": "DMARC — email authentication policy. Improves inbox placement.",
        "required": false,
        "category": "recommended"
      }
    ]
  }
}

The response includes seven DNS records: 1 SES verification TXT, 3 DKIM CNAMEs, 1 MX and 1 SPF TXT for the custom MAIL FROM subdomain, and 1 DMARC TXT (recommended only). Records with required: true must be added for the domain to work; required: false records are optional but improve deliverability.

DNS Record Fields ​

FieldTypeDescription
typestringTXT, CNAME, or MX.
namestringThe hostname to set.
valuestringThe record value.
ttlstringAlways "Auto" — set whatever your DNS provider's default is.
priorityintegerSet to 10 for the MX record; null for everything else.
purposestringHuman-readable description of why this record matters.
requiredbooleantrue for verification + DKIM + custom MAIL FROM records; false for DMARC.
categorystring"verification" (SES ownership), "delivery" (DKIM, MX, SPF), or "recommended" (DMARC).

Automatic setup ​

If the domain's DNS is hosted by a provider that supports Domain Connect — Cloudflare, GoDaddy, IONOS, Plesk and others — the dashboard offers Configure DNS automatically on the domain. It sends you to your provider, which shows exactly these records and writes them on your consent; Krafter then starts verification by itself. The records are the same ones this endpoint returns, minus DMARC, which is left for you to add so an existing _dmarc is never duplicated.

On Cloudflare the CNAMEs are written DNS-only, which is what SES needs. If you publish them by hand instead, keep them unproxied.

TIP

DNS changes can take up to 72 hours to propagate but typically complete within a few minutes to a few hours.


List Domains ​

Returns every domain owned by the authenticated team. The list response does not include dns_records — call Get Domain for the full record list.

GET /domains

Required scope: domains:manage

Example Request ​

bash
curl https://app.krafter.dev/api/v1/domains \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
// 200 OK
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "domain": "example.com",
      "status": "verified",
      "verified_at": "2026-01-15T12:30:00Z",
      "created_at": "2026-01-15T10:00:00Z"
    },
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "domain": "anotherdomain.com",
      "status": "pending",
      "verified_at": null,
      "created_at": "2026-01-16T14:00:00Z"
    }
  ]
}

Get Domain ​

Returns a single domain by ID, including its full dns_records list and current verification status.

GET /domains/:id

Required scope: domains:manage

Example Request ​

bash
curl https://app.krafter.dev/api/v1/domains/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
// 200 OK
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "domain": "example.com",
    "status": "verified",
    "verified_at": "2026-01-15T12:30:00Z",
    "created_at": "2026-01-15T10:00:00Z",
    "dns_records": [
      {
        "type": "TXT",
        "name": "_amazonses.example.com",
        "value": "abc123...",
        "ttl": "Auto",
        "priority": null,
        "purpose": "Domain verification — proves you own this domain",
        "required": true,
        "category": "verification"
      },
      {
        "type": "CNAME",
        "name": "token1._domainkey.example.com",
        "value": "token1.dkim.amazonses.com",
        "ttl": "Auto",
        "priority": null,
        "purpose": "DKIM — cryptographic email signature",
        "required": true,
        "category": "delivery"
      }
    ]
  }
}

Verify Domain ​

Triggers a verification check. Krafter enqueues a job that re-checks DNS and updates the domain's status based on what it finds.

POST /domains/:id/verify

Required scope: domains:manage

Example Request ​

bash
curl -X POST https://app.krafter.dev/api/v1/domains/550e8400-e29b-41d4-a716-446655440000/verify \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

The response is the domain object without dns_records:

json
// 200 OK
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "domain": "example.com",
    "status": "verifying",
    "verified_at": null,
    "created_at": "2026-01-15T10:00:00Z"
  }
}

The status will move to verified (or back to pending/failed) once the asynchronous verification job runs. Poll Get Domain to see the result.


Delete Domain ​

Removes a domain from your team. After deletion you can no longer send from addresses on this domain.

DELETE /domains/:id

Required scope: domains:manage

Example Request ​

bash
curl -X DELETE https://app.krafter.dev/api/v1/domains/550e8400-e29b-41d4-a716-446655440000 \
  -H "Authorization: Bearer kr_live_abc123def456"

Example Response ​

json
// 200 OK
{
  "data": { "deleted": true }
}

Domain Statuses ​

StatusDescription
pendingDomain has been added; DNS records have not been verified yet.
verifyingA verification check is in flight.
verifiedAll required DNS records are in place and the domain is ready to send.
failedVerification ran but at least one required DNS record was missing or wrong.

Built by Krafter Studio