Send Pay Links
API Reference

Domains API

Custom domain management with Vercel integration

Domains API

The Domains API allows you to manage custom domains for your brands with automatic Vercel deployment integration.

Overview

Each brand can have multiple custom domains. Domains are:

  • Automatically configured in Vercel
  • Verified via DNS
  • Associated with specific brands

List Domains

Get all domains for the current brand.

GET /api/admin/domains

Requires: Session cookie

Response

{
  "success": true,
  "domains": [
    {
      "domain": "checkout.example.com",
      "brandId": "brand_xyz",
      "verified": true,
      "primary": true,
      "createdAt": 1704067200000,
      "verification": null,
      "dnsInstructions": []
    },
    {
      "domain": "pay.example.com",
      "brandId": "brand_xyz",
      "verified": false,
      "primary": false,
      "createdAt": 1704153600000,
      "verification": {
        "type": "TXT",
        "domain": "_vercel.pay.example.com",
        "value": "vc-domain-verify=abc123..."
      },
      "dnsInstructions": [
        "Add TXT record: _vercel.pay.example.com → vc-domain-verify=abc123..."
      ]
    }
  ],
  "configured": true
}

Vercel Not Configured Response

{
  "success": false,
  "error": "Vercel not configured. Add VERCEL_TOKEN and VERCEL_PROJECT_ID.",
  "domains": []
}

Add Domain

Add a new custom domain to the current brand.

POST /api/admin/domains
Content-Type: application/json

Requires: Session cookie

Request Body

{
  "domain": "checkout.example.com",
  "primary": false
}

Success Response

{
  "success": true,
  "domain": {
    "domain": "checkout.example.com",
    "brandId": "brand_xyz",
    "verified": false,
    "primary": false,
    "createdAt": 1704067200000,
    "verification": {
      "type": "TXT",
      "domain": "_vercel.checkout.example.com",
      "value": "vc-domain-verify=abc123..."
    },
    "dnsInstructions": [
      "Add TXT record: _vercel.checkout.example.com → vc-domain-verify=abc123..."
    ]
  }
}

Error Response

{
  "success": false,
  "error": "Domain already exists",
  "verification": {
    "type": "TXT",
    "domain": "_vercel.checkout.example.com",
    "value": "vc-domain-verify=abc123..."
  },
  "dnsInstructions": [
    "Add TXT record: _vercel.checkout.example.com → vc-domain-verify=abc123..."
  ]
}

Remove Domain

Remove a domain from the current brand.

DELETE /api/admin/domains?domain=checkout.example.com

Requires: Session cookie

Response

{
  "success": true
}

Verify or Update Domain

Verify domain DNS or update domain settings.

PUT /api/admin/domains
Content-Type: application/json

Requires: Session cookie

Verify Domain DNS

Check if the domain's DNS is properly configured.

{
  "domain": "checkout.example.com",
  "action": "verify"
}

Response

{
  "success": true,
  "verified": true,
  "config": {
    "configuredBy": "CNAME",
    "acceptedChallenges": ["dns-01"]
  }
}

Or if not verified:

{
  "success": true,
  "verified": false,
  "error": "DNS not configured",
  "dnsInstructions": [
    "Add CNAME record: checkout.example.com → cname.vercel-dns.com"
  ]
}

Set Primary Domain

Set a domain as the primary domain for the brand.

{
  "domain": "checkout.example.com",
  "action": "setPrimary",
  "primary": true
}

Response

{
  "success": true
}

DNS Configuration

For Root Domains (example.com)

Add an A record pointing to Vercel's IP:

A @ 76.76.21.21

For Subdomains (checkout.example.com)

Add a CNAME record:

CNAME checkout cname.vercel-dns.com

Verification Record

If verification is required, add a TXT record:

TXT _vercel.checkout.example.com vc-domain-verify=abc123...

Error Responses

StatusErrorDescription
400Domain is requiredMissing domain parameter
400Invalid domain formatDomain doesn't match valid format
400No brand selectedNo brand in session
400Vercel not configuredMissing Vercel credentials
401UnauthorizedSession required
404Domain not foundDomain doesn't exist for brand

Environment Variables

# Vercel Integration
VERCEL_TOKEN=your-vercel-api-token
VERCEL_PROJECT_ID=prj_abc123...
VERCEL_TEAM_ID=team_abc123...  # Optional, for team projects

Code Example

Adding a Custom Domain

async function addDomain(domain: string, primary = false) {
  const response = await fetch('/api/admin/domains', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ domain, primary }),
  });

  const result = await response.json();

  if (!result.success) {
    // Show DNS instructions to user
    console.log('DNS Instructions:', result.dnsInstructions);
    return;
  }

  if (!result.domain.verified) {
    // Domain added but needs DNS verification
    console.log('Please configure DNS:', result.domain.dnsInstructions);
  }
}

Checking Domain Verification Status

async function verifyDomain(domain: string) {
  const response = await fetch('/api/admin/domains', {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify({ domain, action: 'verify' }),
  });

  const result = await response.json();

  if (result.verified) {
    console.log('Domain is verified and ready!');
  } else {
    console.log('Still waiting for DNS...', result.dnsInstructions);
  }
}

On this page