Skip to main content
s.id Logo
Developer Platform

Authentication

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

Which method should you use?

API Keys

Best for your own backend, scheduled jobs, and private automations where the credential never reaches a browser or mobile client.

OAuth 2.0

Best for third-party apps that need user consent and granular, revocable access to an s.id account.

API Keys

Server-to-server access

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 header
Authorization: Bearer sk_live_...
Example request
curl https://api.s.id/v2/links \
  -H "Authorization: Bearer sk_live_..."

Security checklist

  • Keys start with sk_live_ and are shown only once at creation.
  • Request only the minimum scopes your integration needs.
  • Revoke keys immediately if compromised, create a new one.
  • Never expose API keys client-side (browsers, mobile apps).
links:read
links:write
links:archive
links:analytics
qr:read
qr:write
user:read
microsites:read
microsites:write
microsites:delete

OAuth 2.0

Authorization flow

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.

Before redirecting the user

  • Generate an unpredictable state value, store it in the user session, and verify an exact match on callback to prevent CSRF.
  • Use a redirect_uri that exactly matches one registered for your OAuth application.

Public clients

PKCE required, no client secret

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.

Redirect user
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=S256
Exchange code for token
curl -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

Client secret on a trusted backend

For server-rendered or backend applications that can keep a client_secret confidential. PKCE remains optional and is recommended as defense in depth.

Redirect user
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
Exchange code for token
curl -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"

Access token

Expires after 1 hour

Refresh token

Expires after 30 days

Authorization code

Single-use; expires after 10 minutes

Rotate refresh token
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"
Revoke token
curl -X POST https://api.s.id/oauth/revoke \
  -H "Content-Type: application/json" \
  -d '{"token":"TOKEN_TO_REVOKE"}'

Discovery and token operations

Authorization server metadata

https://api.s.id/.well-known/oauth-authorization-server

Discover endpoint URLs, supported scopes, and PKCE methods through RFC 8414 metadata.

Token introspection

POST https://api.s.id/oauth/introspect

Confidential resource servers can check whether a token is active and inspect its scopes.

Token revocation

POST https://api.s.id/oauth/revoke

Revoke access or refresh tokens when a user disconnects your integration.

Authorized user

GET https://api.s.id/oauth/userinfo

Read the profile associated with an OAuth access token carrying user:read.

Ready to start building?

Create an API key in minutes. Free tier included, no credit card required.

Get your API key