workos-domain-verification

📁 workos/skills 📅 3 days ago
4
总安装量
4
周安装量
#51713
全站排名
安装命令
npx skills add https://github.com/workos/skills --skill workos-domain-verification

Agent 安装分布

opencode 4
amp 3
kimi-cli 3
codex 3
gemini-cli 3

Skill 文档

WorkOS Domain Verification

Step 1: Fetch Documentation (BLOCKING)

STOP. Do not proceed until complete.

WebFetch these URLs for source of truth:

If this skill conflicts with the documentation, follow the documentation.

Step 2: Pre-Flight Validation

Environment Variables

Check for required WorkOS credentials:

  • WORKOS_API_KEY – starts with sk_
  • WORKOS_CLIENT_ID – starts with client_

Verify: Both variables are set in .env or .env.local

SDK Installation

Confirm WorkOS SDK is installed:

# Check package.json contains @workos-inc/node
grep "@workos-inc/node" package.json || npm install @workos-inc/node

CRITICAL: SDK must be installed before writing any import statements.

Step 3: Organization Exists (REQUIRED)

All domains must belong to an Organization. You cannot create or verify a domain without an Organization.

Check if organization already exists:

# If you have organization ID
curl https://api.workos.com/organizations/org_123 \
  -H "Authorization: Bearer $WORKOS_API_KEY"

If no organization exists, create one first using the Organizations API (see workos-organizations skill).

Do NOT proceed to Step 4 until you have a valid Organization ID.

Step 4: Implementation Path (Decision Tree)

Choose based on your use case:

Domain verification flow?
  |
  +-- Self-serve (IT admin verifies) --> Admin Portal flow (Step 5A)
  |
  +-- Programmatic (you verify)      --> API flow (Step 5B)

Self-serve = Your customer’s IT admin proves ownership via DNS TXT records through the Admin Portal UI

Programmatic = You integrate domain creation/verification directly into your application code

Step 5A: Admin Portal Flow (Self-Serve)

Create Portal Link

Generate a temporary Admin Portal session link (valid 5 minutes):

import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS(process.env.WORKOS_API_KEY);

const portalLink = await workos.portal.generateLink({
  organization: 'org_123',
  intent: 'domain_verification',
  return_url: 'https://yourapp.com/settings/domains'
});

// portalLink.link - redirect user here

Check documentation for exact method signature – may be createLink or generateLink depending on SDK version.

User Flow

  1. Redirect user to portalLink.link
  2. User adds domain in Admin Portal
  3. User adds DNS TXT record to their domain’s DNS
  4. WorkOS verifies TXT record automatically
  5. User returns to return_url when complete

Verification

Listen for webhook to know when domain is verified, or poll the domain status:

# Get domain status
curl https://api.workos.com/organization_domains/org_domain_123 \
  -H "Authorization: Bearer $WORKOS_API_KEY"

Check documentation for webhook event name – likely domain.verified or similar.

Step 5B: API Flow (Programmatic)

Create Domain

import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS(process.env.WORKOS_API_KEY);

const domain = await workos.organizationDomains.create({
  organization_id: 'org_123',
  domain: 'example.com'
});

// domain.id - save this
// domain.verification_token - share this with domain owner

Check documentation for exact method path – may be workos.domains.create() or similar.

Share Verification Instructions

The domain owner must add this DNS TXT record:

Type: TXT
Host: _workos-challenge (or @ for root)
Value: [domain.verification_token from response]

Check documentation for exact TXT record format – host name may vary.

Trigger Verification

After DNS TXT record is added, trigger verification check:

await workos.organizationDomains.verify({
  domain_id: domain.id
});

Check documentation for exact method name – may be verify(), checkVerification(), or automatic.

Poll for Status

Check if verification succeeded:

const updatedDomain = await workos.organizationDomains.get(domain.id);

if (updatedDomain.state === 'verified') {
  // Domain verified successfully
} else if (updatedDomain.state === 'pending') {
  // Still waiting for DNS propagation
} else if (updatedDomain.state === 'failed') {
  // Verification failed - check TXT record
}

Check documentation for exact state values – may be status instead of state, may use different enum values.

Step 6: List Domains for Organization

Retrieve all domains (verified and unverified) for an organization:

const domains = await workos.organizationDomains.list({
  organization_id: 'org_123'
});

domains.data.forEach(domain => {
  console.log(`${domain.domain}: ${domain.state}`);
});

Verification Checklist (ALL MUST PASS)

Run these commands to confirm integration:

# 1. Check environment variables exist
env | grep WORKOS_API_KEY && env | grep WORKOS_CLIENT_ID

# 2. Check SDK is installed
npm list @workos-inc/node 2>/dev/null || echo "FAIL: SDK not installed"

# 3. Verify organization exists (replace org_123 with your ID)
curl -s https://api.workos.com/organizations/org_123 \
  -H "Authorization: Bearer $WORKOS_API_KEY" | grep '"id"'

# 4. Test domain creation (replace with test domain)
curl -X POST https://api.workos.com/organization_domains \
  -H "Authorization: Bearer $WORKOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"organization_id":"org_123","domain":"test.example.com"}'

# 5. Build succeeds
npm run build

If check #3 fails: Create organization first (see Step 3) If check #4 fails: Check API key permissions or organization ID

Error Recovery

“Organization not found”

Root cause: No organization exists or wrong ID

Fix:

  1. List organizations: curl https://api.workos.com/organizations -H "Authorization: Bearer $WORKOS_API_KEY"
  2. If empty, create organization first
  3. Use correct organization ID in domain creation

“Invalid domain format”

Root cause: Domain contains invalid characters or format

Fix:

  • Use bare domain: example.com not https://example.com
  • No subdomains for verification (unless docs explicitly allow)
  • Check documentation for allowed domain formats

“Domain already exists”

Root cause: Domain already registered to this or another organization

Fix:

  1. List domains: workos.organizationDomains.list()
  2. If domain belongs to current org, use existing domain ID
  3. If domain belongs to different org, cannot claim (security feature)

“Verification failed” / “TXT record not found”

Root cause: DNS TXT record not added correctly or DNS not propagated

Fix:

  1. Check TXT record exists: dig TXT _workos-challenge.example.com or nslookup -type=TXT _workos-challenge.example.com
  2. Verify token matches exactly (no extra quotes or spaces)
  3. Wait for DNS propagation (can take up to 48 hours, usually <15 minutes)
  4. Check documentation for exact TXT record host format

“API key does not have permission”

Root cause: API key lacks domain verification scope

Fix:

  1. Go to WorkOS Dashboard → API Keys
  2. Check key has required permissions
  3. Generate new key if needed

SDK method not found

Root cause: SDK version mismatch with documentation

Fix:

  1. Check SDK version: npm list @workos-inc/node
  2. Check documentation for method names matching your SDK version
  3. Update SDK: npm install @workos-inc/node@latest

Portal link expired

Root cause: Portal links are valid for 5 minutes only

Fix:

  • Generate new portal link immediately before redirecting user
  • Do not cache or reuse portal links

Related Skills

  • workos-organizations: Creating organizations (required before domain verification)
  • workos-sso: SSO connections require verified domains
  • workos-directory-sync: Directory Sync requires verified domains
  • workos-admin-portal: General Admin Portal integration patterns