Skip to content

M2M API clients

An M2M API client is a credential for automation. Unlike an API key, which is a long-lived bearer token with full account access, a client exchanges a secret for a short-lived token and can be restricted to exactly the resources it needs.

Reach for a client when a deploy pipeline, a Terraform run, or an internal service needs API access and you want the blast radius to be small and the credential rotatable.

In the dashboard, Account → API Clients → New client. Name it after what uses it, then tick the scopes it needs.

Terminal window
curl -X POST https://api.siteqwality.com/account/m2m_client/ \
-H "Authorization: Bearer $SITEQWALITY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Deploy pipeline",
"description": "Creates maintenance windows during releases",
"scopes": ["read:monitors", "write:incidents"]
}'
FieldRequiredNotes
nameyes1 to 128 characters after trimming.
descriptionnoFree text.
scopesyesNon-empty. Every entry must be a documented scope.

The response carries the client and, exactly once, the secret:

{
"data": {
"client": {
"id": "<siteqwality-uuid>",
"client_id": "<oauth-client-id>",
"name": "Deploy pipeline",
"scopes": ["read:monitors", "write:incidents"],
"created_at": "2026-08-02T09:00:00Z",
"last_rotated_at": null
},
"client_secret": "<shown once, never again>",
"token_endpoint": "https://api.stytch.com/v1/public/<project>/oauth2/token"
}
}

Creating a client requires the owner role and a verified email address. Listing clients does not.

An account can hold 20 active clients. Revoke an unused one to make room.

Authentication is a standard OAuth2 client-credentials exchange against the token_endpoint the API returned. Do not hardcode that URL; read it from the create or list response.

  1. Exchange the secret for an access token.

    Terminal window
    curl -X POST "$TOKEN_ENDPOINT" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=client_credentials" \
    -d "client_id=$CLIENT_ID" \
    -d "client_secret=$CLIENT_SECRET" \
    -d "scope=read:monitors write:incidents"

    You get back an access_token. Scopes are space-separated.

  2. Call the SiteQwality API with it, exactly like any other bearer token.

    Terminal window
    curl https://api.siteqwality.com/http/jobs \
    -H "Authorization: Bearer $ACCESS_TOKEN"
  3. Refresh when it expires. Tokens are short-lived by design; request a new one rather than caching indefinitely.

Scopes are read:<family> or write:<family>. Nine families exist:

FamilyCovers
monitorsHTTP, TLS, DNS, cron and browser checks
incidentsIncidents, escalation policies, on-call schedules, maintenance windows
notificationsNotification channels, groups, integrations
status_pagesStatus pages and their components
logsLog query, parsers, saved views
metricsMetric query endpoints
tracesTrace search and detail
rumRUM applications and analytics
dashboardsDashboards and widgets

write covers POST, PUT, PATCH and DELETE. Everything else is read. Granting write does not imply read; if a client needs both, grant both.

Two errors distinguish the cases:

ResponseMeaning
403 Insufficient scopesThe family is mapped but this client lacks the scope.
403 This endpoint is not available to M2M API clientsThe surface is not covered by any family.
Terminal window
curl -X POST https://api.siteqwality.com/account/m2m_client/$CLIENT_ID/rotate_secret \
-H "Authorization: Bearer $SITEQWALITY_API_KEY"

Rotation is immediate and has no overlap window. The moment the call returns, the old secret stops working and the new one is shown once. Deploy the new secret before you rotate, not after.

Owner role required. Rotating a revoked client returns 404.

Terminal window
curl -X DELETE https://api.siteqwality.com/account/m2m_client/$CLIENT_ID \
-H "Authorization: Bearer $SITEQWALITY_API_KEY"

Revocation takes effect against the SiteQwality API immediately. Every M2M request is checked against the local client record, so an already-issued token stops being accepted on its very next request.

The token itself remains technically valid at the identity provider until it expires naturally, so treat revocation as “this client can no longer reach SiteQwality” rather than “this token has been destroyed everywhere”.

Revoking twice is harmless. Owner role required.

  • A revoked client, a soft-deleted account, or an unknown client all produce 401.
  • A suspended account can still read through a client, but mutations return 403.
  • Every mutating call a client makes is recorded in the audit log with actor type m2m and the client’s ID.
  • There is no “fetch one client” endpoint; list them and filter.