Overview
All SanMarcSoft domains use Cloudflare for DNS. Records are managed via the Cloudflare API using the API token stored in the pass store. DNS changes should be made via API (not the dashboard) to maintain an audit trail.
Prerequisites
- Cloudflare API token:
pass cloudflare/api-token - Zone IDs are per-domain. Look up via API or Cloudflare dashboard.
Common Zone IDs
| Domain | Zone ID Location |
|---|
| sanmarcsoft.com | pass cloudflare/zones/sanmarcsoft-com |
| verifieddit.com | pass cloudflare/zones/verifieddit-com |
| matthewstevens.org | pass cloudflare/zones/matthewstevens-org |
Procedure: Add a DNS Record
Step 1: Identify the zone
1
2
| ZONE_ID=$(pass cloudflare/zones/<domain>)
CF_TOKEN=$(pass cloudflare/api-token)
|
Step 2: Create the record
1
2
3
4
5
6
7
8
9
10
| curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "subdomain.example.com",
"content": "target.example.com",
"ttl": 1,
"proxied": false
}'
|
Note: ttl: 1 means “automatic” (Cloudflare manages TTL). Set proxied: false for records that must not go through Cloudflare proxy (e.g., Clerk verification records).
Step 3: Verify
1
2
| curl -s "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?name=subdomain.example.com" \
-H "Authorization: Bearer ${CF_TOKEN}" | jq '.result[]'
|
Example: Clerk Custom Domain DNS (verifieddit.com)
Clerk requires 5 DNS records for a custom domain setup. These were created for clerk.verifieddit.com:
Record 1: Frontend API CNAME
1
2
3
4
5
6
7
8
9
10
| curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "clerk.verifieddit.com",
"content": "frontend-api.clerk.services",
"ttl": 1,
"proxied": false
}'
|
Record 2: Accounts CNAME
1
2
3
4
5
6
7
8
9
10
11
| # Points accounts subdomain to Clerk
curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "accounts.verifieddit.com",
"content": "accounts.clerk.services",
"ttl": 1,
"proxied": false
}'
|
Record 3: DKIM (clk._domainkey)
1
2
3
4
5
6
7
8
9
10
| curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "clk._domainkey.verifieddit.com",
"content": "dkim1.f4g7h8j9.clerk.services",
"ttl": 1,
"proxied": false
}'
|
Record 4: DKIM (clk2._domainkey)
1
2
3
4
5
6
7
8
9
10
| curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "clk2._domainkey.verifieddit.com",
"content": "dkim2.f4g7h8j9.clerk.services",
"ttl": 1,
"proxied": false
}'
|
Record 5: Mail CNAME (clkmail)
1
2
3
4
5
6
7
8
9
10
| curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"type": "CNAME",
"name": "clkmail.verifieddit.com",
"content": "mail1.f4g7h8j9.clerk.services",
"ttl": 1,
"proxied": false
}'
|
Important Notes for Clerk DNS
- All Clerk DNS records MUST have
proxied: false – Clerk needs direct access for SSL certificate provisioning. - If records are proxied, Clerk will fail to verify ownership and SSL certificates will not provision.
- After creating all 5 records, wait up to 24 hours for Clerk to verify and provision the SSL certificate.
- The
dkim1, dkim2, and mail1 CNAME targets are unique per Clerk instance – get the exact values from the Clerk Dashboard under “Domains”.
Procedure: List All DNS Records for a Zone
1
2
| curl -s "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records?per_page=100" \
-H "Authorization: Bearer ${CF_TOKEN}" | jq '.result[] | {name, type, content, proxied}'
|
Procedure: Delete a DNS Record
1
2
3
| RECORD_ID="<record-id-from-list>"
curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
-H "Authorization: Bearer ${CF_TOKEN}"
|
Procedure: Update a DNS Record
1
2
3
4
5
6
7
| RECORD_ID="<record-id-from-list>"
curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${RECORD_ID}" \
-H "Authorization: Bearer ${CF_TOKEN}" \
-H "Content-Type: application/json" \
--data '{
"content": "new-target.example.com"
}'
|
Troubleshooting
- Record already exists: Check for existing records with the same name before creating. Use the list endpoint to verify.
- SSL not provisioning (Clerk): Ensure
proxied: false on all Clerk DNS records. Cloudflare proxy interferes with Clerk’s certificate issuance. - Propagation delay: Changes typically propagate within seconds for Cloudflare-managed DNS. External verification (e.g., Clerk) may take up to 24 hours.