propgate docs

API reference › DomainsVerify domain

Verify a domain

POST/v1/domains/:id/checks

Runs every check the domain's profile names, updates its state, and returns a result per requirement. This is the only way a domain moves out of pending: continuous re-checking is the sweeper's job and does not come through here. A customer clicking "verify" during onboarding is what this endpoint is for; reconciling ten thousand domains on a schedule is not, and is not rate-limited the same way either.

No CLI command yet — triggering a check is API-only.

curl -s -X POST https://api.propgate.dev/v1/domains/019fcf7a-2b3c-7d4e-9f5a-6b7c8d9e0f1a/checks \
  -H "authorization: Bearer pg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
{
  "state": "failed",
  "verdict": "fail",
  "requirementsMet": 3,
  "requirementsTotal": 5,
  "requirements": [
    {
      "key": "spf",
      "satisfied": true,
      "verdict": "pass",
      "findings": []
    },
    {
      "key": "dkim",
      "satisfied": false,
      "verdict": "fail",
      "findings": [
        {
          "code": "DKIM_RECORD_MISSING",
          "name": "google._domainkey.yourdomain.dev"
        }
      ]
    }
  ]
}

Every finding carries a diagnosis code and, where the evaluator has them, the DNS name it concerns, what was observed, and what was expected. Findings can appear on a satisfied requirement too, so read satisfied rather than the presence of findings: mx above would still show MX_NULL at pass for a domain that correctly declares it sends no mail.

If the check causes a state transition, whether pending to verified, verified to failed, or any other, the same webhook fires as when the sweeper causes one. See Webhooks for the event names and payload shape.

Rate limit

100 checks a minute per account, separate from the general request limit of 250 requests a second. A check costs up to about 20 upstream DNS queries, aimed at whichever authoritative servers the caller names rather than at servers we operate. That is why this limit is sized as a tripwire rather than a quota: it protects other people's infrastructure, not ours.

HTTP/1.1 429 Too Many Requests
Retry-After: 41

{
  "data": null,
  "error": {
    "message": "rate limit of 100 checks per minute exceeded; try again in 41s"
  },
  "meta": null
}

A Retry-After header names how long to wait. If a real integration reaches this limit, tell us. It is a number we would rather re-measure than have you build around.