API Keys
Best for your own backend, scheduled jobs, and private automations where the credential never reaches a browser or mobile client.
Two ways to authenticate with the s.id API, API keys for server-to-server, OAuth 2.0 for acting on behalf of users.
Choose by trust boundary
Best for your own backend, scheduled jobs, and private automations where the credential never reaches a browser or mobile client.
Best for third-party apps that need user consent and granular, revocable access to an s.id account.
API Keys
API keys authenticate server-to-server integrations. Create one in Dashboard → Developer → API Keys, pick your scopes, and pass it as a Bearer token.
Authorization: Bearer sk_live_...curl https://api.s.id/v2/links \
-H "Authorization: Bearer sk_live_..."links:readlinks:writelinks:archivelinks:analyticsqr:readqr:writeuser:readmicrosites:readmicrosites:writemicrosites:deleteOAuth 2.0
Redirect the user to s.id for consent, verify the callback state, then exchange the single-use code for an access token and rotating refresh token.
Public clients
For SPAs, mobile apps, and CLIs. Create a random code_verifier, send its S256 challenge on authorize, then send the original verifier during token exchange.
https://api.s.id/oauth/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&
scope=links%3Aread%20links%3Awrite&
state=RANDOM_CSRF_VALUE&
code_challenge=BASE64URL_SHA256_VERIFIER&
code_challenge_method=S256curl -X POST https://api.s.id/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=YOUR_CLIENT_ID" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=https://app.example.com/callback" \
-d "code_verifier=ORIGINAL_RANDOM_VERIFIER"Confidential clients
For server-rendered or backend applications that can keep a client_secret confidential. PKCE remains optional and is recommended as defense in depth.
https://api.s.id/oauth/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback&
scope=links%3Aread%20links%3Awrite&
state=RANDOM_CSRF_VALUEcurl -X POST https://api.s.id/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=https://app.example.com/callback"Expires after 1 hour
Expires after 30 days
Single-use; expires after 10 minutes
curl -X POST https://api.s.id/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "refresh_token=CURRENT_REFRESH_TOKEN"curl -X POST https://api.s.id/oauth/revoke \
-H "Content-Type: application/json" \
-d '{"token":"TOKEN_TO_REVOKE"}'https://api.s.id/.well-known/oauth-authorization-serverDiscover endpoint URLs, supported scopes, and PKCE methods through RFC 8414 metadata.
POST https://api.s.id/oauth/introspectConfidential resource servers can check whether a token is active and inspect its scopes.
POST https://api.s.id/oauth/revokeRevoke access or refresh tokens when a user disconnects your integration.
GET https://api.s.id/oauth/userinfoRead the profile associated with an OAuth access token carrying user:read.
Create an API key in minutes. Free tier included, no credit card required.