API reference · Domains
Set up DNS with Cloudflare
https://api.pidgely.com/domains/{id}/dns-provider/cloudflareCreates exactly Pidgely's records in the domain's Cloudflare zone with a Cloudflare API token (Zone → DNS → Edit, plus Zone → Zone → Read). Idempotent, never touches unrelated records, merges into an existing SPF record and keeps an existing DMARC policy. The token is write-only: it is used for this request and never stored, logged or returned. A DNS check runs right after.
Creates or updates exactly Pidgely's records in the domain's Cloudflare zone with a Cloudflare API token (permission Zone → DNS → Edit, plus Zone → Zone → Read to find the zone). Idempotent: running it again changes nothing. Unrelated records are never touched; an existing SPF record at the return path gets Pidgely's include: merged in (never a second SPF record), and an existing DMARC policy is kept. A DNS check is scheduled right after. The token is used for this request only: it is never stored or logged.
Errors (422, field api_token): cloudflare_invalid_token, cloudflare_missing_permission, cloudflare_zone_not_found; 502 cloudflare_unavailable. 10 requests per minute per organization.
Authorization: Bearer pdg_…. An API key with full_access. A sending_access key gets 401 restricted_api_key.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | Resource id UUID. |
Body parameters
JSON object.
| Name | Type | Required | Description |
|---|---|---|---|
api_token |
string | Yes | Cloudflare API token. Used once, never stored. |
Request
This endpoint is in the Node.js SDK; the other SDKs don't cover it yet, so call it over HTTP from them.
import { Pidgely } from 'pidgely';
const pidgely = new Pidgely(process.env.PIDGELY_API_KEY);
const { data, error } = await pidgely.domains.setupCloudflare('0199d7f0-1c2b-7e4d-a5f6-0b9c8d7e6f51', {
apiToken: 'your-cloudflare-api-token',
});
console.log(data ?? error);curl -X POST 'https://api.pidgely.com/domains/0199d7f0-1c2b-7e4d-a5f6-0b9c8d7e6f51/dns-provider/cloudflare' \
-H "Authorization: Bearer $PIDGELY_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"api_token": "your-cloudflare-api-token"
}'Response
200 OK
{
"object": "cloudflare_setup",
"zone": "acme.com",
"records": [
{
"purpose": "dkim",
"type": "TXT",
"name": "pdg202610._domainkey.send.acme.com",
"content": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…",
"action": "created"
},
{
"purpose": "return_path",
"type": "MX",
"name": "bounces.send.acme.com",
"content": "mta.pidgely.com",
"priority": 10,
"action": "created"
},
{
"purpose": "spf",
"type": "TXT",
"name": "bounces.send.acme.com",
"content": "v=spf1 include:_spf.mta.pidgely.com ~all",
"action": "created"
},
{
"purpose": "dmarc",
"type": "TXT",
"name": "_dmarc.send.acme.com",
"content": "v=DMARC1; p=quarantine",
"action": "kept"
}
]
}Response fields
| Name | Type | Required | Description |
|---|---|---|---|
object |
string | Yes | Object type. One of cloudflare_setup. |
zone |
string | Yes | — |
records |
object[] | Yes | DNS records to publish, with their verification status. |
records[].purpose |
string | Yes | One of dkim, return_path, spf, dmarc. |
records[].type |
string | Yes | — |
records[].name |
string | Yes | Record name relative to the domain (for example bounces). |
records[].content |
string | Yes | — |
records[].priority |
integer | No | MX priority. |
records[].action |
string | Yes | kept: the domain's own record was left as is (an existing DMARC policy). One of created, updated, unchanged, kept. |
records[].previous |
string | No | Content an update replaced (an SPF record before Pidgely's include was merged in). |
Errors
Errors have the shape {"statusCode", "name", "message"}. See Errors for the full list.
| Status | Name | When |
|---|---|---|
| 401 | missing_api_key, restricted_api_key |
No Authorization: Bearer header, or a sending_access key called an endpoint that needs full_access. |
| 403 | invalid_api_key, validation_error |
The API key is invalid or revoked, or the request is not allowed for this account (unverified domain, plan limit, paused account). |
| 404 | not_found |
The resource does not exist in this account (or the id is not a valid UUID). |
| 422 | validation_error |
A field is missing or invalid; message names it. |
| 429 | rate_limit_exceeded |
Too many requests per second. Wait for Retry-After seconds. |
| 502 | — | Cloudflare could not be reached (cloudflare_unavailable). |
| 422 | cloudflare_invalid_token |
Cloudflare did not accept the token (malformed, unknown or expired). |
| 422 | cloudflare_missing_permission |
The token cannot edit DNS in the zone. |
| 422 | cloudflare_zone_not_found |
No zone for the domain is visible to the token. |
| 429 | rate_limit_exceeded |
More than 10 setups per minute. |
| 502 | cloudflare_unavailable |
Cloudflare could not be reached. |