propgate docs

API reference › Get startedOverview

API reference

You keep the list of domains. You register each one against a profile, ask us to verify it, and read back which of your requirements are met and which are not. We do not render instructions for your customers — you already have a UI for that, and being wrong about a provider's naming conventions is visible to your customer, not to us.

Base URL https://api.propgate.dev.

The envelope

Every response — success and error alike — is the same shape, so you write one unwrap path rather than one per status code:

{ "data": { ... }, "error": null, "meta": null }
{ "data": null, "error": { "message": "..." }, "meta": null }

Error messages name the field that is wrong and, where the check is a shape check, the value that would fix it — email: Invalid input: expected string, received undefined rather than invalid request. They are written to be actionable by the agent reading them, not only by the person who wrote the integration.

Endpoints

  • POST/v1/signupStart an account. Sends a six-digit code, valid ten minutes. Always answers the same way, whether or not the address is known.
  • POST/v1/signup/confirmConfirm the address and receive an API key. The code is single-use; the key is shown once and never again.
  • POST/v1/api-keysCreate an API key. The secret is returned once and never again — only its hash is stored.
  • GET/v1/api-keysYour keys, oldest first, revoked ones included, each with the address that created it. Prefixes only; no endpoint returns a secret.
  • DELETE/v1/api-keys/:idRevoke a key. Takes effect on the next request. Revoking your last active key is refused.
  • GET/v1/membersWho is on this account. Read-only — a member is added by proving control of a mailbox through signup.
  • POST/v1/profilesCreate a profile version. Editing a profile writes a new version; it never changes an existing one.
  • GET/v1/profiles/:keyThe current version of a profile.
  • POST/v1/domainsRegister a domain against a profile. Does not touch DNS. The domain starts pending.
  • POST/v1/domains/:id/checksVerify the domain now. Runs the checks, updates the state, returns a result per requirement.
  • GET/v1/domainsYour domains, oldest first. Cursor paging, filterable by state and by your own external id.
  • GET/v1/domains/:idThe last known state, per-requirement results, and every lookup behind them.
  • GET/v1/domains/:id/timelineWhat has changed for this domain, newest first. Appended to only when an observation actually differs.
  • DELETE/v1/domains/:idStop tracking the domain.

Start with starting a signup if you don't have a key yet, or authentication for how to use one you already have.

Rate limits

Per account, and sized as tripwires rather than quotas: 250 requests a second overall, and 100 verifications a minute. A 429 names the limit it enforced and carries a Retry-After header.

The request limit is a one-second window rather than the same average over a minute, because a minute-long window permits the whole allowance as a single burst — the shape that actually hurts a connection pool.

The verification limit is the one worth planning around. A check costs up to twenty upstream queries aimed at whichever authoritative servers you name, so it is sized against other people's infrastructure rather than ours. Continuous re-checking is the sweeper's job and does not come through this endpoint or count against this limit.

If a real integration reaches either of these, the number is wrong and we would rather re-measure it than have you work around it. Tell us — the request ceiling is a per-account value we can raise.