propgate docs

Get startedAuthentication

Authentication

Getting a key

Two calls, no sales conversation. The first sends a six-digit code to the address you give it; the second exchanges that code for a key.

curl -X POST https://api.propgate.dev/v1/signup \
  -H "content-type: application/json" \
  -d '{"email":"you@example.com"}'

curl -X POST https://api.propgate.dev/v1/signup/confirm \
  -H "content-type: application/json" \
  -d '{"email":"you@example.com","code":"123456"}'

The code is valid for ten minutes and single-use. Confirmation returns your key once — only a hash is stored, so no endpoint can show it again.

POST /v1/signup answers identically whether or not the address already has an account. That reads like a missing feature until you know it is deliberate: a signup endpoint that says already registered tells whoever holds a leaked address list which of those addresses use us.

Running the flow again on an address that already has an account mints an additional key against the same account rather than a second account. That is also the recovery path if you lose a key, which is why there is no separate sign-in.

To mint a named key without repeating the email flow, see Creating an API key.

Authenticating requests

A bearer token on every request. Keys are stored hashed; the plaintext is shown once when the key is issued and cannot be recovered afterwards.

curl https://api.propgate.dev/v1/domains \
  -H "Authorization: Bearer pg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

PROPGATE_API_KEY overrides whatever confirm wrote to $XDG_CONFIG_HOME/propgate/config.json, which is what makes it the right variable for CI. PROPGATE_API_URL overrides the API the CLI talks to. propgate check needs neither — it resolves locally and never sends the key anywhere.

A 401 distinguishes a key we do not recognise from one that has been revoked. You hold the key either way, so saying which saves you looking for a typo that is not there.

{
  "data": null,
  "error": {
    "message": "invalid API key"
  },
  "meta": null
}
{
  "data": null,
  "error": {
    "message": "this API key has been revoked"
  },
  "meta": null
}