Uptimeify Docs
Agentic registration

Agent authentication (agentic registration)

Register an AI agent and receive a short-lived, read-only access token for the Uptimeify API.

Uptimeify runs a WorkOS-style agentic-registration authorization server at https://uptimeify.io. Agents register, exchange a service-signed identity assertion for a short-lived opaque access token, and call the read-only API. All endpoints below are served only on the canonical host uptimeify.io (a 404 is returned on custom domains).

Discover

curl https://uptimeify.io/.well-known/oauth-authorization-server
curl https://uptimeify.io/.well-known/oauth-protected-resource

The authorization-server metadata follows RFC 8414 (token_endpoint, revocation_endpoint, jwks_uri, grant_types_supported, scopes_supported) and adds an agent_auth extension block with identity_endpoint, claim_endpoint, identity_types_supported (["anonymous", "service_auth"], plus "identity_assertion" when Uptimeify trusts an identity provider), and a skill pointer to /auth.md. Only in that last case does the block also carry identity_assertion, events_supported and events_endpoint; see Identity assertion (ID-JAG). The protected-resource metadata follows RFC 9728.

Register (anonymous)

curl -X POST https://uptimeify.io/agent/identity \
  -H 'Content-Type: application/json' \
  -d '{"type":"anonymous"}'
{
  "registration_id": "reg_…",
  "identity_assertion": "<jwt>",
  "pre_claim_scopes": ["tools.public"],
  "post_claim_scopes": ["api.read"],
  "token_endpoint": "https://uptimeify.io/oauth2/token"
}

The identity_assertion is a ~24h EdDSA JWT: your durable credential. Rate limit: 30 requests/minute per caller.

post_claim_scopes describes the scope a claimed registration reaches (api.read). An anonymous registration is active immediately with tools.public and is usable as-is: claiming it is optional. The response also carries a single-use claim_token (clm_…) and a claim_url: if you want to upgrade this registration to api.read, see Claim flow for how to redeem it.

Register (service_auth)

service_auth registration is claimable-only: it starts pending and mints no token until a signed-in user authorizes it. See Claim flow for the full POST /agent/identity {"type":"service_auth", "login_hint":"…"} request, the human consent step, and how to poll /oauth2/token for the resulting api.read access token.

Register (identity_assertion)

An agent signed in at a trusted identity provider registers with an ID-JAG. When its verified email belongs to an Uptimeify account, the account holder approves it on /claim and chooses which write areas it may use (none are preselected); the resulting token never exceeds that user's current role. See Identity assertion (ID-JAG).

Exchange for an access token

curl -X POST https://uptimeify.io/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer' \
  --data-urlencode 'assertion=<identity_assertion>'
{ "access_token": "wsma_…", "token_type": "Bearer", "expires_in": 3600, "scope": "tools.public" }

The access token is opaque, expires after 1 hour (3600s), and must be re-minted from the identity assertion afterward. Rate limit: 60 requests/minute per caller.

Use (read-only)

curl https://uptimeify.io/api/tools/dns-lookup?domain=deinkunde.com \
  -H 'Authorization: Bearer wsma_…'

Agent tokens are read-only, with one exception: a token for an ID-JAG agent carries the write areas its user approved (see Identity assertion (ID-JAG)). The anonymous tools.public scope reaches only the public check tools (GET /api/tools/*). A claimed, api.read-scoped token (see Claim flow) additionally reaches GET /api/websites*, GET /api/incidents*, and GET /api/health, scoped to the authorizing user's organization (or single customer). Any GET/HEAD request outside the allowlist for the token's scope returns 403 with data.code = agentTokenReadOnly. A write is refused the same way while this server's write kill-switch is off; once it is on, a write outside the token's own granted write scope returns 403 with data.code = agentTokenScopeForbidden instead -- see error codes for both codes.

Revoke

curl -X POST https://uptimeify.io/oauth2/revoke \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'token=wsma_…' \
  --data-urlencode 'token_type_hint=access_token'

Idempotent 200: always succeeds, even for an unknown or already-revoked token.

Common errors

Statuserror / data.codeMeaning
400service_auth_not_enabledThe requested identity type is not enabled yet.
400issuer_not_enabledidentity_assertion (ID-JAG) is off: Uptimeify trusts no identity provider on this deployment.
400invalid_requestUnknown/missing identity type at /agent/identity, or a missing assertion at /oauth2/token.
400unsupported_grant_type/oauth2/token only supports the urn:ietf:params:oauth:grant-type:jwt-bearer grant.
400invalid_grantThe assertion is invalid/expired, or its registration is revoked/expired.
403agentTokenReadOnlyAn agent token attempted a write while the write kill-switch is off, or an off-allowlist read path. See error codes.
403agentTokenScopeForbiddenThe write kill-switch is on, but the token's granted scope does not cover this write. See error codes.
404-Requested on a custom domain, or (discovery endpoints only) the agent-auth feature is off.
503-/agent/identity or /oauth2/token called while the agent-auth feature is off (no signing key configured).
429-Rate limit exceeded on /agent/identity, /oauth2/token, or /oauth2/revoke.

anonymous and service_auth are both enabled. service_auth registration and the claim ceremony have their own error codes: see Claim flow and the error codes reference. identity_assertion (ID-JAG) is available once Uptimeify trusts an identity provider; its codes are listed on Identity assertion (ID-JAG).

On this page